MailKit 2.15.0 版本断线问题

Posted

技术标签:

【中文标题】MailKit 2.15.0 版本断线问题【英文标题】:MailKit version 2.15.0 disconnection issue 【发布时间】:2021-12-11 04:30:56 【问题描述】:

我正在使用 MailKit 版本 2.15.0。尝试使用 DisconnectAsync 断开客户端时,出现以下错误

ClientDisconnect method()==> Exception Message:  The ReadAsync method cannot be called when another read operation is pending., Exception String: System.NotSupportedException:  The ReadAsync method cannot be called when another read operation is pending.
         at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](TIOAdapter adapter, Memory`1 buffer)
         at MailKit.Net.Pop3.Pop3Stream.ReadAheadAsync(Boolean doAsync, CancellationToken cancellationToken)
         at MailKit.Net.Pop3.Pop3Stream.ReadLineAsync(Stream ostream, Boolean doAsync, CancellationToken cancellationToken)
         at MailKit.Net.Pop3.Pop3Engine.ReadLineAsync(Boolean doAsync, CancellationToken cancellationToken)
         at MailKit.Net.Pop3.Pop3Engine.ReadResponseAsync(Pop3Command pc, Boolean doAsync)
         at MailKit.Net.Pop3.Pop3Engine.IterateAsync(Boolean doAsync)
         at MailKit.Net.Pop3.Pop3Client.SendCommandAsync(Boolean doAsync, CancellationToken token, String command)
         at MailKit.Net.Pop3.Pop3Client.DisconnectAsync(Boolean quit, Boolean doAsync, CancellationToken cancellationToken)

下面是我用来断开客户端的代码

private async Task DisconnectClient(Hashtable markAsRead, EmailServer emailServer)

    pollingInProgress = false;
    await emailServer.ClientDisconnect(markAsRead);
    markAsRead.Clear();

   internal void MarkAsRead(Hashtable markAsRead)
        
            emailBinding.emailSource().MarkRead(markAsRead);
        

        internal async Task ClientDisconnect(Hashtable markAsRead)
        
            try
            
                if (!emailBinding.emailSource().IsConnected)
                
                    await emailBinding.Connect();
                

                FlushClient(markAsRead);

                await emailBinding.Disconnect();
            
            catch (Exception e)
            
                AttachWorkerLogs(string.Format("ClientDisconnect method()==> Exception Message: 0, Exception String: 1", e.Message, e.ToString()));
                throw;
            
        

        private void FlushClient(Hashtable markAsRead)
        
            MarkAsRead(markAsRead);
        

最后像这样调用disconnect方法:

public async Task Disconnect()
        
            try
            
                if (client.IsConnected)
                
                    await client.DisconnectAsync(true);
                
            
            catch (Exception e)
            
                AttachLogger(string.Format("Disconnect method()==> Exception Message: 0, Exception String: 1", e.Message, e.ToString()));
                throw;
            

        

我无法弄清楚到底是什么问题。

【问题讨论】:

PS 我也试过 await emailBinding.Disconnect().ConfigureAwait(false);还有 Task.WaitAll(emailBinding.Disconnect()); 【参考方案1】:

异常消息清楚地表明您正在尝试同时从多个线程读取 SslStream。

由于 MailKit 不是多线程的,这意味着您正在有效地尝试同时从多个线程对同一个 Pop3Client 执行 2 个或更多操作。

换句话说,问题不在于您调用了 Disconnect,问题在于当您的代码试图从服务器下载消息或其他内容时,您正在调用 Disconnect。

【讨论】:

以上是关于MailKit 2.15.0 版本断线问题的主要内容,如果未能解决你的问题,请参考以下文章

游戏中的断线连接展示(PC版本)

使用 mailkit 发送的多部分电子邮件的文本/纯文本版本未正确接收

Log4j 1:如何在不将版本更新到 2.15.0 的情况下缓解 log4j 中的漏洞

WebSocket 断线重连引入心跳的原因

Mailkit 第一步问题 c#

MailKit 设置附加后看到的 MessageFlag