我有一个发送电子邮件的功能,如下所示:
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)如何强制该方法的同步执行?
谢谢
发布于 2016-11-06 06:52:03
1)为什么我要得到这个异常?
你得到这个例外是因为,
2)如何强制同步执行此方法?
你可以强制同步执行,
例如:
var task = new Task(() => { ... });
task.RunSynchronously();检查当您在原始任务中抛出错误时,以及当原始任务通过注释/取消注释虚拟异常而完成时,下面的程序是如何运行的。您可以在http://rextester.com/上执行以下程序
using System;
using System.Threading.Tasks;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
try
{
DoSomething().Wait();
}
catch (AggregateException ex)
{
Console.WriteLine(ex.InnerException.Message);
}
Console.WriteLine("DoSomething completed");
}
public static async Task DoSomething()
{
await Task.Factory.StartNew(() =>
{
System.Threading.Thread.Sleep(1000);
Console.WriteLine("Doing Something");
// throw new Exception("Something wen't wrong");
}).ContinueWith(task =>
{
Console.WriteLine(task.Exception.InnerException.Message);
}, TaskContinuationOptions.OnlyOnFaulted);
}
}
}如果您只在使用ContinueWith方法记录任何错误时才记录异常,那么您可以摆脱该ContinueWith,并在原始任务中放置一个尝试捕获块,以捕获任何异常并记录它们。
static void Main(string[] args)
{
DoSomething().Wait();
Console.WriteLine("DoSomething completed");
Console.ReadKey();
}
public static async Task DoSomething()
{
await Task.Factory.StartNew(() =>
{
try
{
System.Threading.Thread.Sleep(1000);
Console.WriteLine("Doing Something");
throw new Exception("Something wen't wrong");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
});
}否则,如果您想在原始任务完成后做一些额外的工作,您可以这样做:
namespace SO
{
using System;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
DoSomething().Wait();
Console.WriteLine("DoSomething completed");
Console.ReadKey();
}
public static async Task DoSomething()
{
await Task.Factory.StartNew(() =>
{
System.Threading.Thread.Sleep(1000);
Console.WriteLine("Doing Something");
// throw new Exception("Something wen't wrong");
}).ContinueWith(task =>
{
if (task.Status == TaskStatus.Faulted)
{
// log exception
Console.WriteLine(task.Exception.InnerException.Message);
}
else if (task.Status == TaskStatus.RanToCompletion)
{
// do continuation work here
}
});
}
}
}https://stackoverflow.com/questions/40446298
复制相似问题