每当我从ASP.NET MVC应用程序中调用smtpClient.SendAsync(…)时,即使从未调用SendAsyncCancel(),也会自动取消异步请求.
另一方面,同步.发送(…)请求通过就好了.
我的EmailService服务包装器处理从我的ASP.NET MVC 3应用程序中发送带有SmtpClient的异步电子邮件.通过StructureMap将服务实例注入到每个MVC控制器中,它将新的SmtpClient实例包装在using(…){}语句中.
这是我的SmtpClient的EmailService.SendAsync包装器方法:
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; } }
这是我的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.Subject)); } else { _logger.Info(string.Format("Sent email to {0} with subject [{1}].",mail.Subject)); } }
解决方法
它肯定是一个处置问题.当您处置客户端时,它会取消任何未完成的异步操作.
您应该在Email_OnCompleted中处置客户端.
关于在哪里处置的SO帖子:Dispose SmtpClient in SendComplete?