You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中POP3客户端无法实时获取新邮件的解决方案咨询

问题:无法获取程序运行期间收到的最新邮件

我用EAGetMail库在C#里开发邮件获取程序,目前能正常获取程序启动前的邮件,但无法获取程序运行期间收到的新邮件,尝试重启SSL连接或客户端也没用。相关代码如下:

using EAGetMail;
using System;
using System.Globalization;
using System.IO;

namespace PopServer
{
    class Program
    {
        static string _generateFileName(int sequence)
        {
            DateTime currentDateTime = DateTime.Now;
            return string.Format("{0}-{1:000}-{2:000}.eml",
                currentDateTime.ToString("yyyyMMddHHmmss", new CultureInfo("en-US")),
                currentDateTime.Millisecond,
                sequence);
        }
        static void Main(string[] args)
        {
            try
            {
                
                string localInbox = string.Format("{0}\\inbox", Directory.GetCurrentDirectory());
                
                if (!Directory.Exists(localInbox))
                {
                    Directory.CreateDirectory(localInbox);
                }

                MailServer oServer = new MailServer("popserver.com",
                        "username@mail.com",
                        "password",
                        ServerProtocol.Pop3);
                
                oServer.SSLConnection = true;
                oServer.Port = 995;

                MailClient oClient = new MailClient("TryIt");
                oClient.Connect(oServer);

                MailInfo[] infos = oClient.GetMailInfos();
                Console.WriteLine("Total {0} email(s)\r\n", infos.Length);
//我曾尝试利用SSL连接让程序更新邮件,但它仅能获取程序启动前的邮件
                while (oServer.SSLConnection)
                {
                    for (int i = 0; i < infos.Length; i++)
                    {
                        MailInfo info = infos[i];
                        Console.WriteLine("Index: {0}; Size: {1}; UIDL: {2}",
                            info.Index, info.Size, info.UIDL);


                        Mail oMail = oClient.GetMail(info);

                        Console.WriteLine("From: {0}", oMail.From.ToString());
                        Console.WriteLine("Subject: {0}\r\n", oMail.Subject);
                        Console.WriteLine("Body: {0}\r\n", oMail.TextBody);

                      

                        string fileName = _generateFileName(i + 1);
                        string fullPath = string.Format("{0}\\{1}", localInbox, fileName);


                        oMail.SaveAs(fullPath, true);

                        //删除已读邮件
                        //oClient.Delete(info);
                    }
                }
               

                
                oClient.Quit();
                Console.WriteLine("Completed!");
            }
            catch (Exception ep)
            {
                Console.WriteLine(ep.Message);
            }
        }
    }
}

核心原因

你的代码存在两个关键问题:

  1. MailInfo[] infos = oClient.GetMailInfos();仅在程序启动时执行一次,后续循环只会反复处理这批旧邮件,从未重新从服务器拉取新邮件列表。
  2. while (oServer.SSLConnection)是无效的循环条件——SSL连接状态不会自动变更,导致程序陷入死循环,一直重复处理初始邮件。

解决思路与方案

1. 定时轮询拉取新邮件

将获取邮件列表的逻辑放入循环内部,每隔固定时间重新调用GetMailInfos(),同时用**UIDL(邮件唯一标识符)**记录已下载的邮件,避免重复处理。

2. 修正循环逻辑

把死循环改为带时间间隔的轮询,比如每隔30秒检查一次新邮件,减少资源占用。

修改后的示例代码

using EAGetMail;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Threading;

namespace PopServer
{
    class Program
    {
        // 记录已下载的邮件UIDL,避免重复下载
        static HashSet<string> _downloadedUids = new HashSet<string>();

        static string _generateFileName(int sequence)
        {
            DateTime currentDateTime = DateTime.Now;
            return string.Format("{0}-{1:000}-{2:000}.eml",
                currentDateTime.ToString("yyyyMMddHHmmss", new CultureInfo("en-US")),
                currentDateTime.Millisecond,
                sequence);
        }

        static void Main(string[] args)
        {
            try
            {
                string localInbox = Path.Combine(Directory.GetCurrentDirectory(), "inbox");
                
                if (!Directory.Exists(localInbox))
                {
                    Directory.CreateDirectory(localInbox);
                }

                MailServer oServer = new MailServer("popserver.com",
                        "username@mail.com",
                        "password",
                        ServerProtocol.Pop3);
                
                oServer.SSLConnection = true;
                oServer.Port = 995;

                MailClient oClient = new MailClient("TryIt");
                oClient.Connect(oServer);

                // 初始化已下载邮件的UIDL列表
                MailInfo[] initialInfos = oClient.GetMailInfos();
                foreach (var info in initialInfos)
                {
                    _downloadedUids.Add(info.UIDL);
                }
                Console.WriteLine("初始邮件数量:{0}\r\n", initialInfos.Length);

                // 定时轮询新邮件,间隔30秒
                while (true)
                {
                    MailInfo[] latestInfos = oClient.GetMailInfos();
                    int newMailCount = 0;

                    foreach (var info in latestInfos)
                    {
                        // 只处理未下载过的邮件
                        if (!_downloadedUids.Contains(info.UIDL))
                        {
                            newMailCount++;
                            Console.WriteLine("新邮件 - Index: {0}; UIDL: {1}", info.Index, info.UIDL);

                            Mail oMail = oClient.GetMail(info);
                            Console.WriteLine("发件人: {0}", oMail.From.ToString());
                            Console.WriteLine("主题: {0}\r\n", oMail.Subject);
                            Console.WriteLine("内容: {0}\r\n", oMail.TextBody);

                            string fileName = _generateFileName(newMailCount);
                            string fullPath = Path.Combine(localInbox, fileName);
                            oMail.SaveAs(fullPath, true);

                            // 标记为已下载
                            _downloadedUids.Add(info.UIDL);
                        }
                    }

                    if (newMailCount > 0)
                    {
                        Console.WriteLine("本次新增邮件:{0}封\r\n", newMailCount);
                    }
                    else
                    {
                        Console.WriteLine("无新邮件,30秒后重试...\r\n");
                    }

                    // 等待30秒后再次检查
                    Thread.Sleep(30000);
                }

                // 注:以上为死循环,实际项目需添加退出逻辑,此处Quit不会执行
                // oClient.Quit();
                // Console.WriteLine("Completed!");
            }
            catch (Exception ep)
            {
                Console.WriteLine(ep.Message);
            }
        }
    }
}

额外说明

  • POP3协议限制:POP3是拉取式协议,无推送机制,只能通过轮询获取新邮件。若需更高实时性,建议改用IMAP协议(EAGetMail支持IMAP),IMAP可保持连接并接收服务器的新邮件通知。
  • 连接稳定性:长时间保持POP3连接可能被服务器断开,建议每次轮询后断开连接,下次轮询时重新连接,或在捕获连接异常时自动重连。
  • 资源优化:轮询间隔不要过短,根据需求设置10-60秒的合理间隔,避免给服务器和本地程序造成不必要的压力。

内容的提问来源于stack exchange,提问作者Shawn_Medinsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 01:57:18