通过等待任务或访问其Exception属性,未观察到任务的异常.结果,未观察到的例外是

Mon*_*RPG 97 c# wpf exception task task-parallel-library

这意味着什么以及如何解决它?

我正在使用TPL任务.

整个错误

通过等待任务或访问其Exception属性,未观察到任务的异常.结果,终结器线程重新抛出了未观察到的异常.

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

mscorlib程序

Ree*_*sey 153

如果您创建了一个Task,并且您没有调用task.Wait()或尝试检索a的结果,那么Task<T>当垃圾收集器收集任务时,它将在最终确定期间拆除您的应用程序.有关详细信息,请参阅MSDN的TPL中的异常处理页面.

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

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);
}
Run Code Online (Sandbox Code Playgroud)

通过以上操作,您可以阻止任何任务拆除应用程序并通过以下方式记录:

Task.Factory.StartNew( () => 
   { 
       // Do your work...
   }).LogExceptions();
Run Code Online (Sandbox Code Playgroud)

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

  • 重要说明:这仅适用于`.Net 4.0`.默认情况下,".net 4.5"中的异常处理已更改为**而不会删除应用程序**.有关详细信息,请参阅[.NET 4.5中的任务异常处理](http://blogs.msdn.com/b/pfxteam/archive/2011/09/28/10217876.aspx) (30认同)
  • 为了增加娱乐性,在一个名为你选择的四个字母单词的类中有一个静态存根方法`Off`,并将它用于你的全部延续.有助于对抗这一特殊例外的一些被压抑的挫败感. (17认同)

Mar*_*ell 41

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

  • 处理任务直接失败(使用ContinueWith(...)订阅,检查.IsFaulted.ExceptionTask在参数)
  • 处理TaskScheduler.UnobservedTaskException事件,并标记它(e.SetObserved()记录错误后调用)

  • +1 - 添加一个 - 如果你的继续只是检查`IsFaulted`,你可以使用`OnlyOnFaulted`继续选项并避免手动检查...... (4认同)
  • 需要调用+1来提及`UnobservedTaskExceptionEventArgs`上的`SetObserved`. (3认同)