【问题标题】:Who is waiting for a Task by default?默认情况下谁在等待任务?
【发布时间】:2016-08-22 11:03:02
【问题描述】:

我在使用 ContinueWith 时遇到了问题。在回调中,当第一个任务出错时,我没有观察/处理Exception。我在这里发现了在这种情况下会发生什么:
Proper way to use .ContinueWith for Tasks

请记住,如果您自己的延续没有观察到 例外,等待整个工作流程的人 完成将是观察它的人。

这让我想知道:
谁是未等待的Task 的服务员?
默认情况下谁在等待Task

例如:

public int HowOldAmI()
{
    Task t = Task.Run(async () => {
            await Task.Delay(5000); 
            throw new Exception("Something happened");
    });
    return 42;
}

在这种情况下,在等待Task

【问题讨论】:

  • 没有,在你展示的情况下。没有什么“隐式”等待任务完成 - 如果您选择创建任务而不等待它,任何异常都会转到未观察到的异常处理程序。
  • 好的,谢谢@JonSkeet。 未观察到的异常处理程序 是否记录在某处?我问的原因是我的崩溃报告库正在捕获这些异常,尽管没有发生真正的崩溃,所以我正在尝试正确处理异常,以便它们不会出现在我的崩溃报告中。
  • 查看安德鲁的答案...

标签: .net task


【解决方案1】:

没有任何东西在等待那些任何东西都没有等待的任务。这就是为什么等待它们很重要,否则所有这些异常都将被吞没,您可能不知道程序中存在逻辑错误。 .NET 的早期版本具有不同的逻辑,并且在出现未观察到的异常时会导致进程崩溃。

还有一个事件有助于处理未观察到的异常(例如,至少将它们记录在某处):TaskScheduler.UnobservedTaskException

另请参阅此问题中的讨论:Unobserved Task exceptions in .NET 4.5 still crash app

【讨论】:

  • 好的,谢谢。所以 UnobservedTaskException 处理程序将被调用,即使我用t.ContinueWith((previousTask) => { /* Code that does not observe the Exception */ }); 继续我的第一个Task t
  • 是的,完全正确。您需要访问任务的ResultException 属性,或者等待其结果为异常为observed。否则,它将传递给该事件。
猜你喜欢
  • 2012-01-30
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多