每当我从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?