MailKit的使用心得

Mailkit 支持 Pop3、IMAP,STMP是目前.Net端最全的邮件开源项目了。

1、Pop3:跟其他的pop3操作类没有太大区别,跟OpenPop.NET等都差不多

2、IMAP:功能上比Pop3要强大太多,优势是功能强大、可以搜索邮箱的所有文件夹,Pop3只能搜索INBOX(收件箱),如果要做收信,还是IMAP首选。缺点是每一次操作都会与服务器同步,比如读取了邮件,服务器上也会变为已读,而Pop3不会。

如果做邮箱收信的话,还是必须同时支持 Pop3、IMAP。

大体使用方式:

1、在设计模式上实现一个抽象类GetEmail_base

2、然后再写一个IMAP、Pop3操作类并继承抽象类( GetMail_IMAP : GetEmail_base、GetMail_Pop : GetEmail_base)

3、最后在写一个GetEmail类对外使用,通过字段 private GetEmail_base GetEmail_Bll 将IMAP、Pop3操作合并统一操作邮件。

4、具体实现比较多,由于GetEmail类夹杂了很多我自有的判断,所以不方便上传。

今天要说的并不是Mailkit的基础操作,而是遇到过的一个大坑!!!!

在使用过程中,我曾遇到一个很蛋疼的问题,跑着跑着Mailkit 突然就卡住了,既不报错,也没有异常,就在那卡着,无论是Connect、Login又或者是其他任何操作,即便你设置了imapClient.Timeout、pop3Client.Timeout。

最开始十分疑惑,也没有找到原因,在尝试折腾了N次,并查看了源码之后发现,虽然我调用的是同步方法(Mailkit 支持异步),可是Mailkit 内部实际还是用的等待异步来执行的,而异步执行中有一个很重要的参数cancellationToken我没有填,因为这个参数支持默认值,一开始我以为既然有默认值,而且同步执行应该可以不需要设置这个参数,设置 Timeout就可以了,事实证明还是太年轻了。cancellationToken、Timeout分管的是两个不同的东西。

解决方法:在每个带有cancellationToken参数的方法中都带上自定义参数

var TokenSource = new CancellationTokenSource(30000);//30s超时

folder.Open(FolderAccess.ReadWrite, cancellationToken: TokenSource.Token);

var msg = folder.GetMessage(Index, cancellationToken: TokenSource.Token); 

folder.Close(cancellationToken: TokenSource.Token);

imapClient.Identify(clientImplementation, cancellationToken: TokenSource.Token);

IMAP、Pop3都需要!!!设置好之后再也没有出现卡住不动的情况

 

ImapClient扩展类

    public static class ImapClientEx
        {
        /// <summary>
        /// task取消时间
        /// </summary>
        private static readonly int CancelTokenMillSecends = 30000;
        /// <summary>
        /// 模拟邮件客户端信息(是出自:https://www.cnblogs.com/zuimengaitianya/p/8579315.html)
        /// </summary>
        /// <param name="imapClient"></param>
        public static void Identify(this ImapClient imapClient)
            {
            List<ImapImplementation> Implements = new List<ImapImplementation>()
                {
                new ImapImplementation() {Name = "foxmail",Version = "7.2.9.156", },
                new ImapImplementation() {Name = "outlook",Version = "14.0.4760.1000", },
                };
            Func<ImapCapabilities, ImapCapabilities, bool> HasImapCapabilitiesId = (sourceFlag, targetFlag) => { return ((sourceFlag | targetFlag) == sourceFlag); };
            if (HasImapCapabilitiesId(imapClient.Capabilities, ImapCapabilities.Id))
                {
                var clientImplementation = new ImapImplementation
                    {
                    Name = "foxmail",
                    Version = "7.2.9.156",
                    };
                var TokenSource = new CancellationTokenSource(CancelTokenMillSecends);
                var serverImplementation = imapClient.Identify(clientImplementation, cancellationToken: TokenSource.Token);
                }
            }

        public static int GetMessageCount(this ImapClient imapClient, IMailFolder folder, bool closeFolder = false)
            {
            if (imapClient == null)
                return 0;
            var TokenSource = new CancellationTokenSource(CancelTokenMillSecends);
            if (!folder.IsOpen)
                folder.Open(MailKit.FolderAccess.ReadWrite, cancellationToken: TokenSource.Token);
            var Count = folder.Count;
            if (closeFolder)
                folder.Close(cancellationToken: TokenSource.Token);

            return Count;
            }
        public static int GetMessageCount(this ImapClient imapClient, IMailFolder folder, SearchQuery Query, bool closeFolder = false)
            {
            var Count = imapClient.GetManyMessageUids(folder, Query, closeFolder)?.Count;
            return Count ?? 0;
            }

        public static List<UniqueId> GetManyMessageUids(this ImapClient imapClient, IMailFolder folder, SearchQuery Query, bool closeFolder = false)
            {
            if (imapClient == null)
                return null;
            //List<IMailFolder> mailFolderList = imapClient.GetFolders(imapClient.PersonalNamespaces[0]).ToList();//取所有文件夹
            if (folder == null)
                return null;
            var TokenSource = new CancellationTokenSource(CancelTokenMillSecends);
            if (!folder.IsOpen)
                folder.Open(FolderAccess.ReadWrite, cancellationToken: TokenSource.Token);
            var uids = folder.Search(Query, cancellationToken: TokenSource.Token);
            if (closeFolder)
                folder.Close(cancellationToken: TokenSource.Token);
            return uids?.ToList();
            }

        public static MimeMessage GetMessage(this ImapClient imapClient, UniqueId Id, IMailFolder folder, bool closeFolder = false)
            {
            if (imapClient == null)
                return null;
            //List<IMailFolder> mailFolderList = imapClient.GetFolders(imapClient.PersonalNamespaces[0]).ToList();//取所有文件夹
            if (folder == null)
                return null;
            var TokenSource = new CancellationTokenSource(CancelTokenMillSecends);
            if (!folder.IsOpen)
                folder.Open(MailKit.FolderAccess.ReadWrite, cancellationToken: TokenSource.Token);
            var msg = folder.GetMessage(Id, cancellationToken: TokenSource.Token);
            if (closeFolder)
                folder.Close(cancellationToken: TokenSource.Token);
            return msg;
            }
        public static MimeMessage GetMessage(this ImapClient imapClient, int Index, IMailFolder folder, bool closeFolder = false)
            {
            if (imapClient == null)
                return null;
            //List<IMailFolder> mailFolderList = imapClient.GetFolders(imapClient.PersonalNamespaces[0]).ToList();//取所有文件夹
            if (folder == null)
                return null;
            var TokenSource = new CancellationTokenSource(CancelTokenMillSecends);
            if (!folder.IsOpen)
                folder.Open(FolderAccess.ReadWrite, cancellationToken: TokenSource.Token);
            var msg = folder.GetMessage(Index, cancellationToken: TokenSource.Token); 
            if (closeFolder)
                folder.Close(cancellationToken: TokenSource.Token);
            return msg;
            }

        public static IList<IMessageSummary> FetchMessage(this ImapClient imapClient, List<UniqueId> Ids, IMailFolder folder, MessageSummaryItems Item, bool closeFolder = false)
            {
            if (imapClient == null)
                return null;
            //List<IMailFolder> mailFolderList = imapClient.GetFolders(imapClient.PersonalNamespaces[0]).ToList();//取所有文件夹
            if (folder == null)
                return null;
            var TokenSource = new CancellationTokenSource(CancelTokenMillSecends);
            if (!folder.IsOpen)
                folder.Open(FolderAccess.ReadWrite, cancellationToken: TokenSource.Token);
            var msg = folder.Fetch(Ids, Item, cancellationToken: TokenSource.Token);
            if (closeFolder)
                folder.Close(cancellationToken: TokenSource.Token);
            return msg;
            }
        public static IList<IMessageSummary> FetchMessage(this ImapClient imapClient, List<int> indexes, IMailFolder folder, MessageSummaryItems Item, bool closeFolder = false)
            {
            if (imapClient == null)
                return null;
            //List<IMailFolder> mailFolderList = imapClient.GetFolders(imapClient.PersonalNamespaces[0]).ToList();//取所有文件夹
            if (folder == null)
                return null;
            var TokenSource = new CancellationTokenSource(CancelTokenMillSecends);
            if (!folder.IsOpen)
                folder.Open(FolderAccess.ReadWrite, cancellationToken: TokenSource.Token);
            var msg = folder.Fetch(indexes, Item, cancellationToken: TokenSource.Token);
            if (closeFolder)
                folder.Close(cancellationToken: TokenSource.Token);
            return msg;
            }

        public static bool DeleteMessage(this ImapClient imapClient, UniqueId Id, IMailFolder folder, SearchQuery Query, bool closeFolder = false)
            {
            if (imapClient == null)
                return false;
            //List<IMailFolder> mailFolderList = imapClient.GetFolders(imapClient.PersonalNamespaces[0]).ToList();//取所有文件夹
            if (folder == null)
                return false;
            var TokenSource = new CancellationTokenSource(CancelTokenMillSecends);
            if (!folder.IsOpen)
                folder.Open(FolderAccess.ReadWrite, cancellationToken: TokenSource.Token);
            //设置状态
            folder.SetFlags(Id, MessageFlags.Deleted, false, cancellationToken: TokenSource.Token);
            //或者删除邮件
            folder.RemoveFlags(Id, MessageFlags.Deleted, false);
            //主要针对Exchange 让删除指令执行
            folder.Expunge(cancellationToken: TokenSource.Token);

            if (closeFolder)
                folder.Close(cancellationToken: TokenSource.Token);
            return true;
            }
        public static bool DeleteMessage(this ImapClient imapClient, int EmailIndex, IMailFolder folder, SearchQuery Query, bool closeFolder = false)
            {
            if (imapClient == null)
                return false;
            //List<IMailFolder> mailFolderList = imapClient.GetFolders(imapClient.PersonalNamespaces[0]).ToList();//取所有文件夹
            if (folder == null)
                return false;
            var TokenSource = new CancellationTokenSource(CancelTokenMillSecends);
            if (!folder.IsOpen)
                folder.Open(FolderAccess.ReadWrite, cancellationToken: TokenSource.Token);
            //设置状态
            folder.SetFlags(EmailIndex, MessageFlags.Deleted, false, cancellationToken: TokenSource.Token);
            //或者删除邮件
            folder.RemoveFlags(EmailIndex, MessageFlags.Deleted, false, cancellationToken: TokenSource.Token);
            //主要针对Exchange 让删除指令执行
            folder.Expunge(cancellationToken: TokenSource.Token);

            if (closeFolder)
                folder.Close(cancellationToken: TokenSource.Token);
            return true;
            }
        }

 

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MailKit是一个C#编写的开源邮件处理库,用于在.NET平台上发送和接收电子邮件。该库提供了一系列强大的功能,如SMTP(Simple Mail Transfer Protocol)和POP3(Post Office Protocol 3)协议的支持,可以方便地实现邮件的发送和接收。 要下载MailKit DLL,可以按照以下步骤进行操作: 1. 打开MailKit的官方网站(https://github.com/jstedfast/MailKit)。 2. 在页面上找到“Release”或“下载”按钮,并点击进入下载页面。 3. 在下载页面上,找到“Latest release”或“最新版本”的选项,并选择适合您的项目和.NET平台的版本。 4. 点击相应的版本号,进入该版本的下载页。 5. 在下载页上,找到相关的DLL文件(通常以“MailKit.dll”或类似的形式命名),并点击下载链接。您可以选择下载可执行文件或源代码文件,具体视您的需求而定。 6. 下载完成后,您可以将所需的DLL文件添加到您的项目中进行使用。具体的添加方法会因您使用的开发环境而有所不同,可参考相应的文档或搜索相关教程进行操作。 需要注意的是,MailKit是一个开源项目,因此可以在其官方网站上找到最新的版本和文档。同时,建议定期检查更新以获取最新的功能和修复。 总之,如果您需要在.NET平台上实现邮件的发送和接收,MailKit是一个功能强大且易于使用的选择。通过下载相应的MailKit DLL文件并添加到您的项目中,可以方便地使用该库来处理电子邮件

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值