我有以下代码:
public async Task AsyncMethod()
{
await Task.Factory.StartNew(() =>
{
throw new Exception();
});
}
public ActionResult Index()
{
var t1 = Task.Factory.StartNew(() => { throw new Exception(); });
var t2 = Task.Factory.StartNew(() => { throw new Exception();});
var t3 = Task.Factory.StartNew(async () => { await AsyncMethod(); });
try
{
Task.WaitAll(t1, t2, t3);
}
catch (AggregateException ex)
{
var count1 = ex.InnerExceptions.Count;
var count2 = ex.Flatten().InnerExceptions.Count;
throw;
}
return View();
}
我想了解为什么count1和count2变量是2而不是3,如何在AsyncMethod中获取第三个异常?
最佳答案
我想了解为什么count1和count2变量是2而不是3,如何在AsyncMethod中获取第三个异常?Task.Factory.StartNew
返回基本的Task
。如果将其传递给async
委托,则返回的Task
仅表示async
方法的开始(直到它产生给调用方的点为止)。
您应该将Task.Run
与async
代码一起使用。 Task.Run
将为Task
委托创建一个async
包装器,因此从Task
返回的Task.Run
表示整个async
方法。
Stephen Toub具有an excellent blog post detailing the differences between Task.Run
and Task.Factory.StartNew
。
另外,如usr所述,每当在GUI或ASP.NET上下文中阻塞Task
而不是await
时,死锁都会出现问题。我有a blog post that goes into detail about this deadlock problem。您应该使用await Task.WhenAll
而不是Task.WaitAll
。
因此,这是同时应用了两个更改的代码:
public async Task AsyncMethod()
{
await Task.Run(() =>
{
throw new Exception();
});
}
public async Task<ActionResult> Index()
{
var t1 = Task.Run(() => { throw new Exception(); });
var t2 = Task.Run(() => { throw new Exception();});
var t3 = Task.Run(async () => { await AsyncMethod(); });
try
{
await Task.WhenAll(t1, t2, t3);
}
catch (Exception)
{
var ex1 = t1.Exception.InnerException;
var ex2 = t2.Exception.InnerException;
var ex3 = t3.Exception.InnerException;
throw;
}
return View();
}
关于c# - 在异步委托(delegate)中捕获异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14102135/