我有这个代码:
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 中获取第三个异常?
最佳答案
I would like to understand why the count1 and count2 variables are 2 and not 3 and how can I get the third exception inside AsyncMethod?
Task.Factory.StartNew
返回一个基本的 Task
。如果你给它传递一个 async
委托(delegate),那么返回的 Task
只代表 async
方法的开始(直到它屈服于它的点来电者)。
您应该将 Task.Run
与 async
代码一起使用。 Task.Run
将为 async
委托(delegate)创建一个 Task
包装器,因此从 Task 返回的
表示整个Task
.Runasync
方法。
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/