在 Task.WhenAll 中捕获异常

Catching exceptions in Task.WhenAll

A class 具有异步方法 MonitorAsync(),它启动 long-running 并行操作。我有 collection 个 monitors;这些都拉开序幕如下:

    internal async Task RunAsync()
    {
        var tasks = monitors.Select((p) => p.Value.MonitorAsync());
        await Task.WhenAll(tasks);
    }

如果 monitor 摔倒了,我需要知道(基本上我会 运行 把它重新爬起来)。我研究了 ContinueWith 等等,但是当 运行 并行执行一堆异步任务时,我如何才能确保我明确知道任务何时结束?

对于上下文,RunAsync 基本上是我应用程序的核心。

如果您想知道一个结束的时间(并且不影响其他),ContinueWith() 可能是一种方式。

或者,循环中的 WaitAny 怎么样?

while(anyTaskUnfinished){
    await Task.WaitAny(tasks);
}
//Stuff you do after WhenAll() comes here

我不确定您是否必须删除已经完成的任务。或者如果它等待任何新完成。

你可以试试这个:

If you do not want to call the Task.Wait method to wait for a task's completion, you can also retrieve the AggregateException exception from the task's Exception property

internal async Task RunAsync()
{
    var tasks = monitors.Select((p) => p.Value.MonitorAsync());
    try
    {
        await Task.WhenAll(tasks);
    }
    catch (Exception)
    {
        foreach (var task in tasks.Where(x => x.IsFaulted))
        foreach (var exception in task.Exception.InnerExceptions)
        {
            // Do Something
        }
    }
}

参考:Exception handling (Task Parallel Library)

If a monitor falls over, I need to know (basically I will run it up again).

最简单的方法是在单独的方法中定义此逻辑:

internal async Task RunAsync()
{
  var tasks = monitors.Select(p => MonitorAndRestart(p));
  await Task.WhenAll(tasks);

  async Task MonitorAndRestart(P p)
  {
    while (true)
    {
      try { await p.Value.MonitorAsync(); }
      catch { ... }
      p.Restart();
    }
  }
}