【发布时间】:2016-11-06 15:04:51
【问题描述】:
我有一个发送电子邮件的功能,如下所示:
public async Task SendEmail(string from, string to, string subject, string body, bool isBodyHtml = false)
{
await Task.Run(() =>
{
using (SmtpClient smtp = new SmtpClient(host, port))
{
smtp.Credentials = new NetworkCredential(userName, password);
smtp.EnableSsl = true;
smtp.SendCompleted += SmtpOnSendCompleted;
MailMessage message = new MailMessage(from, to, subject, body);
message.IsBodyHtml = isBodyHtml;
smtp.Send(message);
}
}).ContinueWith(task =>
{
LoggingService.Instance.BusinessLogger.Error(task.Exception.Flatten().InnerException);
}, TaskContinuationOptions.OnlyOnFaulted);
}
如您所见,它不是“真正的异步”,而是“延迟执行”,因此我可以调用此方法,并且不会阻塞当前调用线程。
现在,我有时需要一种方法来等待电子邮件发送完毕,然后再继续。所以我这样调用我的 SendMail() 方法:
EmailService.Instance.SendEmail("from@blah.com", "to@blah.com", "Subject", "Body text").Wait();
最后带有 .Wait()。
由于某种原因使用 .Wait() - 试图强制同步执行,导致异常:
System.Threading.Tasks.TaskCanceledException:任务被取消
问题:
1) 为什么会出现此异常?
2) 如何强制同步执行该方法?
谢谢
【问题讨论】:
-
您遇到了异常,因为任务在“已取消”状态下完成(
Wait()并没有“导致”这种情况,它只是传播了该信息)。 -
如果您取出 ContinueWith 并使用 try/catch,它的行为是否相同?目前尚不清楚您为什么要在此处使用 ContinueWith,但可能发生的情况是,由于主要任务(来自
Task.Run)成功完成,继续任务被取消。 -
另外,
SendCompleted事件仅与SendAsync方法一起引发。同步 Send 方法不会引发事件。是否有理由不使用基于任务的方法SendMailAsync? -
为什么这个问题被大量否决?它是有效的和好的!
标签: c# async-await task-parallel-library wait