【问题标题】:A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was通过等待任务或访问其异常属性未观察到任务的异常。结果,未观察到的异常是
【发布时间】:2011-12-14 13:06:13
【问题描述】:

这是什么意思以及如何解决?

我正在使用 TPL 任务。

整个错误

在等待任务或访问其异常属性时未观察到任务的异常。结果,未观察到的异常被终结器线程重新抛出。

在 System.Threading.Tasks.TaskExceptionHolder.Finalize()

mscorlib

【问题讨论】:

    标签: c# wpf exception task task-parallel-library


    【解决方案1】:

    如果您创建了一个任务,并且您从未调用task.Wait() 或尝试检索Task<T> 的结果,那么当垃圾收集器收集该任务时,它将在完成过程中关闭您的应用程序。有关详细信息,请参阅 Exception Handling in the TPL 上的 MSDN 页面。

    这里最好的选择是“处理”异常。这可以通过延续来完成 - 您可以将延续附加到任务,并记录/吞下/等发生的异常。这提供了一种干净的方式来记录任务异常,并且可以写成一个简单的扩展方法,即:

    public static void LogExceptions(this Task task)
    {
        task.ContinueWith( t =>
        {
             var aggException = t.Exception.Flatten();
             foreach(var exception in aggException.InnerExceptions)
                 LogException(exception);
        }, 
        TaskContinuationOptions.OnlyOnFaulted);
    }
    

    通过上述方法,您可以防止任何任务通过以下方式关闭应用程序并记录它:

    Task.Factory.StartNew( () => 
       { 
           // Do your work...
       }).LogExceptions();
    

    或者,您可以订阅TaskScheduler.UnobservedTaskException 并在那里处理。

    【讨论】:

    • 为了增加娱乐性,在一个名为您选择的四个字母单词的类中拥有一个静态存根方法Off,并将其用于您的全面延续。有助于消除因这个特殊例外而被压抑的一些挫败感。
    • @MonsterMMORPG 是的 - 您基本上必须在某处捕获或处理异常。只要你在某个地方处理它,你的核心问题就会消失。
    • 在调用 ContinueWith 之前任务是否有可能抛出异常?
    • @TimSylvester 框架仍然会通过延续来映射它,即使它发生在延续附加的“之前”
    • 重要提示:这仅对.Net 4.0 是必需的。默认情况下,.net 4.5 中的异常处理已更改为不关闭应用程序。在Task Exception Handling in .NET 4.5中查看更多信息
    【解决方案2】:

    当然;这意味着Task 在被留给垃圾回收后最终确定,但任务本身失败了。有两个修复:

    • 任务失败直接处理(使用ContinueWith(...)订阅,在参数中Task上勾选.IsFaulted.Exception
    • 处理TaskScheduler.UnobservedTaskException 事件,并将其标记为已观察(记录错误后调用e.SetObserved()

    【讨论】:

    • +1 - 加上一个 - 如果您的延续只是检查IsFaulted,您可以使用OnlyOnFaulted 延续选项并避免手动检查...
    • 实际上这发生在我在 tpl 任务中调用公共静态函数的地方。使用 try catch 会解决这个问题吗?我真的需要创建另一个任务并等待它吗?谢谢
    • +1 表示需要调用 UnobservedTaskExceptionEventArgs 上的 SetObserved
    猜你喜欢
    • 2012-02-29
    • 2016-11-25
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 2012-09-01
    相关资源
    最近更新 更多