C#Task.WhenAll处理异常

时间:2018-10-08 08:26:37

标签: c# asynchronous task

我需要有关简单Task.WhenAll C#代码的帮助。我同时有多达50个不同的任务被触发,但是其中一些调用可能返回错误消息。

我正在尝试编写异常处理代码,以便我可以处理有效的代码(确实可以处理),但是捕获出错的代码,以便可以对它们执行其他代码。

有AggregateException,但是有没有办法查看哪个调用/输入创建了该异常?

由于严格的公司政策,我无法共享实际的代码,但示例如下:

List<ListDetails> libs = getListDetails();
var tasks = new Task<List<ItemDetails>>[libs.Count];
for (int i = 0; i < libs.Count; i++)
{
    tasks[i] = getListItems(libs[i].ServerRelativeUrl, libs[i].ListId);
}

try
{
    await Task.WhenAll(tasks);
}
catch(AggregateException aex)
{
    //Capture which Server RelativeUrls and ListIDs that failed.    
}

3 个答案:

答案 0 :(得分:2)

您应该检查InnerExceptions属性,或者可以使用AggregateException.Flatten方法,如文档所示:

try {
     task1.Wait();
  }
  catch (AggregateException ae) {
     foreach (var e in ae.Flatten().InnerExceptions) {
        if (e is CustomException) {
           Console.WriteLine(e.Message);
        }
        else {
           throw;
        }
     }
  }

这将为您提供子任务引发的所有异常,但是不幸的是,无法知道哪个任务引发了特定的异常。您将需要研究堆栈跟踪。

答案 1 :(得分:2)

您可以在等待后查询原始任务:

urandom

答案 2 :(得分:0)

您应该创建一个异步任务数组,然后在将每个任务添加到数组中时,应将一个带有lambda表达式的匿名函数放置在ContinueWith(){}中。这是一个示例:

var tasks = new List<Task>(); 
tasks.add(t.ContinueWith(o =>
{
    if(o.IsFaulted){
        Console.WriteLine(o.Exception?.InnerException);
        return;
        }

        Console.WriteLine(o.Result);
  }));

 tasks.WhenAll().ContinueWith(o=>{

Console.WriteLine("All Done!")
});