简体   繁体   English

在 Task.WhenAll 中捕获异常

[英]Catching exceptions in Task.WhenAll

A class has async method MonitorAsync() , which starts a long-running parallel operation. class 具有异步方法MonitorAsync() ,它启动长时间运行的并行操作。 I have a collection of these monitors ;我收集了这些monitors these are all kicked off as follows:这些都开始如下:

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

If a monitor falls over, I need to know (basically I will run it up again).如果monitor摔倒了,我需要知道(基本上我会再次运行它)。 I've looked into ContinueWith and so on but when running a bunch of async tasks in parallel, how can I ensure I definitely know when one ends?我已经研究过ContinueWith等等,但是当并行运行一堆异步任务时,我如何确保我确定知道一个任务何时结束?

For context, RunAsync is basically the core of my application.对于上下文, RunAsync基本上是我的应用程序的核心。

If a monitor falls over, I need to know (basically I will run it up again).如果显示器摔倒了,我需要知道(基本上我会再次运行它)。

The easiest way to do this is to define this logic in a separate method:最简单的方法是在单独的方法中定义此逻辑:

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();
    }
  }
}

If you want to know when one ends (and that does not affect the others), ContinueWith() could be the way.如果您想知道一个何时结束(并且这不会影响其他人),ContinueWith() 可能是一种方式。

Alternatively, how about WaitAny in a loop?或者,WaitAny 在循环中怎么样?

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

I am uncertain if you have to remove already finished Tasks.我不确定您是否必须删除已完成的任务。 Or if it waits for any newly finishing.或者,如果它等待任何新的完成。

You can try this:你可以试试这个:

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如果您不想调用 Task.Wait 方法来等待任务完成,您还可以从任务的 Exception 属性中检索 AggregateException 异常

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
        }
    }
}

Reference: Exception handling (Task Parallel Library)参考: 异常处理(任务并行库)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM