任务和任务.WaitAll具有超时异常处理

时间:2011-08-18 16:51:56

标签: c# task-parallel-library

当使用Task.WaitAll等待任务并在WaitAll超时时指定超时时,我还必须单独观察任何未完成的任务(例如通过注册延续)?

This thread让我认为答案是肯定的,但我还没有找到其他证实这一点的内容。

var random = new Random();
var tasks = Enumerable.Range(0, 10).Select((i) => Task.Factory.StartNew(() => {
        // Sleep 5-15 seconds
        Thread.Sleep(random.Next(5000, 15000));
        throw new Exception("Some exception.");
    }
)).ToArray();

try {
    // Wait for 10 seconds
    Task.WaitAll(tasks, 10000);
} catch (AggregateException) {
    // Swallow
}

// Check to see how many tasks were unfinished
tasks.Where(t => !t.IsCompleted).Count().Dump("Unfinished count: ");

// Is this neccessary to avoid exceptions being thrown on the finalizer?
foreach (Task task in tasks) {
    task.ContinueWith(t => t.Exception, TaskContinuationOptions.OnlyOnFaulted);
}

2 个答案:

答案 0 :(得分:2)

为避免崩溃终结器,您必须观察Task正文引发的异常。要观察Task异常,您必须执行以下操作之一:

  1. 访问例外属性
  2. 致电Task.Wait / WaitAll / WaitAny
  3. 注册仅在任务出现故障时才会运行的续集
  4. 你做了什么绝对是必要的,以避免崩溃终结者。

答案 1 :(得分:0)

使用LINQPad v4.31进行测试表明答案是肯定的,因为如果您注释掉foreach,则会为每个未完成的任务获得未处理的异常对话框。

我相信我理解为什么会出现这种情况,但如果有人想通过各种手段对这种行为进行更具技术性的解释,那就去吧。