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

如何用C#的EAGetMail库通过POP3动态读取新邮件?

解决方案:用EAGetMail+POP3实现新邮件自动读取

完全可以通过EAGetMail结合POP3服务器实现新邮件动态读取,不需要重启应用或自行搭建服务器。你的代码问题出在没有定期重新拉取邮件列表,且循环逻辑有误,以下是具体修正方案:

问题分析

  1. 你仅在应用启动时调用了一次GetMailInfos(),后续循环一直复用旧的邮件列表,自然无法获取新到达的邮件。
  2. 循环条件oServer.SSLConnection是SSL连接的配置项(始终为true),会导致无限循环重复处理旧邮件,且没有请求间隔,会对服务器造成不必要的压力。
  3. 缺少已处理邮件的记录机制,会重复下载同一批邮件。

修正后的代码

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

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)
        {
            // 记录已处理过的邮件UIDL,避免重复处理
            HashSet<string> processedUidl = new HashSet<string>();
            // 邮件检查间隔(单位:毫秒,这里设为30秒)
            int checkInterval = 30000;
            MailClient oClient = null;

            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;

                oClient = new MailClient("TryIt");
                oClient.Connect(oServer);
                Console.WriteLine("已连接到POP3服务器,开始监听新邮件...");

                // 首次拉取邮件并标记为已处理
                MailInfo[] initialInfos = oClient.GetMailInfos();
                foreach (var info in initialInfos)
                {
                    processedUidl.Add(info.UIDL);
                }
                Console.WriteLine($"初始化完成,已标记{initialInfos.Length}封历史邮件为已处理");

                // 持续监听新邮件
                while (true)
                {
                    try
                    {
                        // 重新拉取最新的邮件列表
                        MailInfo[] infos = oClient.GetMailInfos();
                        int newMailCount = 0;

                        foreach (MailInfo info in infos)
                        {
                            // 只处理未记录过的新邮件
                            if (!processedUidl.Contains(info.UIDL))
                            {
                                newMailCount++;
                                Console.WriteLine($"发现新邮件:Index: {info.Index}; UIDL: {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);

                                // 标记该邮件为已处理
                                processedUidl.Add(info.UIDL);

                                // 可选:删除服务器上的邮件
                                // oClient.Delete(info);
                            }
                        }

                        if (newMailCount > 0)
                        {
                            Console.WriteLine($"已处理{newMailCount}封新邮件");
                        }
                        else
                        {
                            Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 未发现新邮件");
                        }

                        // 等待指定间隔后再次检查
                        Thread.Sleep(checkInterval);
                    }
                    catch (Exception loopEx)
                    {
                        Console.WriteLine($"检查邮件时出错:{loopEx.Message}");
                        // 尝试重新连接
                        if (!oClient.IsConnected)
                        {
                            Console.WriteLine("尝试重新连接服务器...");
                            oClient.Connect(oServer);
                        }
                        // 等待一段时间后重试
                        Thread.Sleep(checkInterval);
                    }
                }
            }
            catch (Exception ep)
            {
                Console.WriteLine($"初始化出错:{ep.Message}");
            }
            finally
            {
                // 确保退出时断开连接
                oClient?.Quit();
                Console.WriteLine("已断开与服务器的连接");
            }
        }
    }
}

关键改进点

  • 新增已处理邮件记录:用HashSet<string>存储已处理的邮件UIDL(POP3协议中唯一标识邮件的字符串),避免重复下载。
  • 定期拉取邮件列表:在循环内部每次重新调用GetMailInfos(),获取最新的邮件状态。
  • 添加检查间隔:用Thread.Sleep()设置检查间隔(比如30秒),减少对服务器的请求频率。
  • 异常处理增强:处理循环中的异常,连接断开时自动重试连接。
  • 优化路径处理:用Path.Combine()替代字符串拼接,避免路径分隔符问题。

内容的提问来源于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:15:38