I have this code:
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();
}
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.StartNewreturns a basicTask. If you pass it anasyncdelegate, then the returnedTaskonly represents the beginning of theasyncmethod (up until the point it yields to its caller).You should be using
Task.Runwithasynccode.Task.Runwill create aTaskwrapper for anasyncdelegate, so theTaskreturned fromTask.Runrepresents the entireasyncmethod.Stephen Toub has an excellent blog post detailing the differences between
Task.RunandTask.Factory.StartNew.Also, as usr mentioned, you have problems with deadlocks whenever you block on
Taskrather thanawaitit in a GUI or ASP.NET context. I have a blog post that goes into detail about this deadlock problem. You should useawait Task.WhenAllinstead ofTask.WaitAll.So, here’s your code with both changes applied: