SmtpClient.SendAsync调用自动取消

Pet*_*ron 8 asp.net asp.net-mvc asynchronous smtp smtpclient

每当我smtpClient.SendAsync(...)从ASP.NET MVC应用程序中调用时,异步请求都会自动取消,即使SendAsyncCancel()从未调用过.

.Send(...)另一方面,同步请求通过就好了.

我的EmailService服务包装器处理SmtpClient从我的ASP.NET MVC 3应用程序中发送异步电子邮件.通过StructureMap将服务实例注入到每个MVC控制器中,StructureMap将新SmtpClient实例包装在using (...) { }语句中.

这是我的EmailService.SendAsync包装方法SmtpClient:

public void SendAsync(EmailMessage message)
{
    try
    {
        using (var smtpClient = new SmtpClient(_cfg.Host, _cfg.Port)
        {
            EnableSsl = _cfg.EnableSsl,
            Credentials = _credentials
        })
        {
            smtpClient.SendCompleted += new SendCompletedEventHandler(Email_OnCompleted);

            var mailMessage = new MailMessage(message.From, message.To)
                                {
                                    Subject = message.Subject,
                                    Body = message.Body
                                };

            smtpClient.SendAsync(mailMessage, message);

            _logger.Info(string.Format("Sending async email to {0} with subject [{1}]", message.To, message.Subject));
        }
    }
    catch (Exception ex)
    {
        _logger.Error("Async email error: " + ex);
        throw;
    }

}
Run Code Online (Sandbox Code Playgroud)

这是我的Email_OnCompleted代表:

public void Email_OnCompleted(object sender, AsyncCompletedEventArgs e)
{
    var mail = (EmailMessage)e.UserState;

    if (e.Error != null)
    {
        _logger.Error(string.Format("Error sending email to {0} with subject [{1}]: {2}", mail.To, mail.Subject, e.Error));
    }
    else if (e.Cancelled)
    {
        _logger.Warn(string.Format("Cancelled email to {0} with subject [{1}].", mail.To, mail.Subject));
    }
    else
    {
        _logger.Info(string.Format("Sent email to {0} with subject [{1}].", mail.To, mail.Subject));
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么异步电子邮件被取消,但同步电子邮件通过正常?这可能是一个处置问题吗?

And*_*bel 13

它肯定是一个处置问题.当您处置客户端时,它会取消任何未完成的异步操作.

你应该把客户处理掉Email_OnCompleted.

关于在哪里处置的SO帖子:在SendComplete中处理SmtpClient?

  • 太棒了!我撕掉了using(...)语句,异步发送现在完美无缺.谢谢,安德斯! (3认同)
  • 更准确地说......“当您处置客户端时,它会取消任何未完成的异步操作。” = 当您处置 SmtpClient 时,它会取消该类实例的所有未完成的异步操作。 (2认同)