首页 > 解决方案 > 使用安全连接时 ImapClient、SmtpClient 和 Pop3Client Connect 方法的大延迟

问题描述

尝试从 MailKit 连接 SMTP 或 IMAP 客户端时,我注意到最多延迟 13 秒。似乎延迟发生在 MailKit 库中对 AuthenticateAsClient 方法的调用上。我在这里找到了问题的解释https://blogs.msdn.microsoft.com/alejacma/2011/09/27/big-delay-when-calling-sslstream-authenticateasclient/

这在 MailKit 中不是问题,但我想知道使用 MailKit 解决此问题的最佳解决方法。似乎 cancelToken 传递给 MailKit Connect 方法并没有取消此方法调用。当您想在 SmtpClient 连接时关闭进程时,这是一个问题,因为您想等待运行此代码的专用线程完成。

这是我的解决方法,但不是很优雅

public override void Connect(string host, int port = 0, SecureSocketOptions options = SecureSocketOptions.Auto, CancellationToken cancellationToken = default(CancellationToken))
{
    var connectionTask = smtpClient.ConnectAsync(host, port, options, cancellationToken);

    Task.WhenAny(connectionTask, cancellationToken.WhenCanceled()).GetAwaiter().GetResult();

    cancellationToken.ThrowIfCancellationRequested();
}

public static class Extensions
{
    public static Task WhenCanceled(this CancellationToken cancellationToken)
    {
        var tcs = new TaskCompletionSource<bool>();
        cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).SetResult(true), tcs);
        return tcs.Task;
    }
}

这在大多数情况下都可以工作,但如果取消令牌,连接将保持连接状态(因为 AuthenticateAsClient 不可取消),并且用户可能会在 smtpClient 仍在尝试连接时尝试执行另一个命令。

我正在寻找更好的方法来取消 MailKit 上下文中的 Connect 方法。

标签: mailkit

解决方案


推荐阅读