任务 WhenAll 的异常处理

4
我希望在一些任务可能失败的情况下使用Task.WhenAll,并且仍然需要已完成任务的结果数据。根据MSDN,如果提供的任何任务以故障状态完成,则返回的任务也将以故障状态完成,其中其异常将包含来自每个提供的任务的未包装异常集合的聚合。但是,它没有说明Task.WhenAll在这种情况下是否仍会等待其余任务完成。有人能对此问题提供任何澄清吗?

1
我认为最后的WhenAny是一个打字错误,因为WhenAny自然不会等待,但WhenAll会。 - Sami Kuhmonen
只需编写一个包含两个TaskCompletionSource对象的小测试,以“感受”它的工作原理。 - Sir Rufo
@SamiKuhmonen 是的,谢谢指出拼写错误。 - cubesnyc
2个回答

7

根据文档所述:

创建一个任务,在可枚举集合中所有Task对象都已完成时任务才会完成。

因此,它将等待所有任务完成,无论是否已经抛出异常或被取消。然后它将聚合可能的取消和异常,并定义其状态。给定任务的结果将在原始任务中,以及异常和取消。


-1

您可以通过将所有任务的主体包装在try catch块中,并使用适当的数据结构作为任务的结果类型来轻松处理您的要求,以便您可以了解任务是否失败。

一个示例可能有助于更好地理解我想告诉您的内容。

public async static void Main(string[] args)
{
   var task1 = GetIntegerAsync();
   var task2 = GetAnotherIntegerAsync();
   var result = await Task.WhenAll(new[] {task1, task2});

   foreach(var res in results)
   {
     // show a different message depending on res.isFailed
   }
}

private static async Task<(int result, bool isFailed)> GetIntegerAsync()
{
   try
   {
     await Task.Delay(1000).ConfigureAwait(false);
     return (10, false);
   }
   catch(Exception)
   {
     return (default(int), true);
   }
}

private static async Task<(int result, bool isFailed)> GetAnotherIntegerAsync()
{
   try
   {
     await Task.Delay(600).ConfigureAwait(false);
     throw new Exception("Something bad happened...");
   }
   catch(Exception)
   {
     return (default(int), true);
   }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接