【问题标题】:Task WhenAll exception handling任务WhenAll异常处理
【发布时间】:2018-10-07 00:04:24
【问题描述】:

我希望在某些任务可能失败的情况下使用 Task.WhenAll,但我仍然需要来自其余已完成任务的结果数据。

根据MSDN

如果提供的任何任务在故障状态下完成,则 返回的任务也将在故障状态下完成,其中它的 异常将包含未包装集合的聚合 每个提供的任务的例外。

但是,它没有说的是 Task.WhenAll 是否仍将等待其余任务在该实例中完成。任何人都可以就这个问题提供任何澄清吗?

【问题讨论】:

  • 我认为最后的WhenAny是一个错字,因为WhenAny自然不会等待,但WhenAll会。
  • 只需用两个 TaskCompletionSource 对象编写一个小测试来“感受”它的工作原理
  • @SamiKuhmonen 是的,感谢您指出错字。

标签: c#


【解决方案1】:

正如文档所说:

创建一个任务,该任务将在可枚举集合中的所有任务对象都完成时完成。

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

【讨论】:

    【解决方案2】:

    您可以通过将所有任务的主体包装在 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);
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-05
      • 1970-01-01
      • 2014-03-06
      • 1970-01-01
      • 2015-07-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多