等待具有 OnlyOnFaulted Continuation 的任务会导致 AggregateException

Posted

技术标签:

【中文标题】等待具有 OnlyOnFaulted Continuation 的任务会导致 AggregateException【英文标题】:Waiting on a Task with a OnlyOnFaulted Continuation causes an AggregateException 【发布时间】:2011-07-04 15:59:29 【问题描述】:

我有一些简单的代码作为重现:

var taskTest = Task.Factory.StartNew(() =>

    System.Threading.Thread.Sleep(5000);

).ContinueWith((Task t) =>

    Console.WriteLine("ERR");
, TaskContinuationOptions.OnlyOnFaulted);

try

    Task.WaitAll(taskTest);

catch (AggregateException ex)

    foreach (var e in ex.InnerExceptions)
        Console.WriteLine(e.Message + Environment.NewLine + e.StackTrace);

但是,我在 try catch 块中抛出了一个意外的 TaskCanceledException(它位于 AggregateException InnerExceptions 对象中)。 “任务已取消”。

为什么我会收到此异常?任务的继续永远不会触发,它没有产生异常,但我在等待时仍然得到聚合异常......

我希望有人能解释这对我有什么意义:)

【问题讨论】:

我的情况和你一模一样。我认为只传播上一个任务的结果会更加优雅和直观。抛出一个 TaskCanceledException 是相当令人惊讶的...... 【参考方案1】:

您不是在等待 OnlyOnFaulted 延续的任务 - 您正在等待on 该延续(由ContinueWith 返回)。延续永远不会触发,因为原始任务正常返回,所以它的行为就像它被取消一样。

对我来说很有意义。

我怀疑你想创建任务,添加延续,然后等待 原始 任务:

var taskTest = Task.Factory.StartNew(() =>

    System.Threading.Thread.Sleep(5000);

);
taskTest.ContinueWith((Task t) =>

    Console.WriteLine("ERR");
, TaskContinuationOptions.OnlyOnFaulted);

【讨论】:

很好的解释,只有一条评论,在这种情况下,最好不要使用 Factory.StartNew() 方法,因为任务可以在定义延续之前开始。在这里,我将使用 new Task() ctor,然后设置 ContinueWith(),最后调用 Start() 方法。有意义吗? @JorgeFioranelli:为什么在定义延续之前启动任务会有问题?我相信 TPL 会毫无问题地处理这个问题。 不确定,但我相信有可能任务在添加延续之前抛出异常,然后不会调用处理程序。我说的对吗? @JorgeFioranelli - 如果延续附加到已完成的任务,如果任务完成但出现异常,它将立即执行。 (如果任务没有出错,它将取消。) 如果我们等待原始任务,并且我们比它的异常处理继续完成更快,那么应用程序可以在异常处理程序完成之前退出,对吗?我们怎样才能最好地避免这种情况?等待继续,但不考虑它是如何完成的? await continuationTask.ContinueWith(task => );

以上是关于等待具有 OnlyOnFaulted Continuation 的任务会导致 AggregateException的主要内容,如果未能解决你的问题,请参考以下文章

根据每个唯一标识符的条件更新值

R语言ggplot2可视化:可视化连续(数值)变量的堆叠的直方图自定义堆叠直方图中不同分组条形的色彩自定义直方图bin的宽度基于宽度自动选择bin的个数(Histogram for Contin

将一行中的金额添加到具有相同主键的不同行中的金额

java中的关键字

等待具有异步过滤器的等待message.awaitReaction

等待具有不同结果的多个任务