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