C# 任务';未通过等待任务或访问其exception属性观察到的异常。因此,未被观察到的例外情况是

C# 任务';未通过等待任务或访问其exception属性观察到的异常。因此,未被观察到的例外情况是,c#,wpf,exception,task,task-parallel-library,C#,Wpf,Exception,Task,Task Parallel Library,这意味着什么?如何解决 我正在使用TPL任务 全部错误 通过等待任务或访问其exception属性,未观察到任务的异常。结果,未观察到的异常被终结器线程重新抛出 在System.Threading.Tasks.TaskExceptionHolder.Finalize()中 mscorlib 如果您创建了一个任务,并且从未调用Task.Wait()或尝试检索任务的结果,当垃圾收集器收集该任务时,它将在完成过程中关闭您的应用程序。有关详细信息,请参阅上的MSDN页面 这里最好的选择是“处理”异常。这

这意味着什么?如何解决

我正在使用TPL任务

全部错误

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

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

mscorlib


如果您创建了一个任务,并且从未调用
Task.Wait()
或尝试检索
任务的结果,当垃圾收集器收集该任务时,它将在完成过程中关闭您的应用程序。有关详细信息,请参阅上的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();

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

当然;这意味着一个
任务
在被留给垃圾收集后完成了,但任务本身失败了。有两种修复方法:

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

+1-添加一项-如果您的继续操作除了检查
IsFaulted
之外什么都不做,那么您可以使用
OnlyOnFaulted
继续选项并避免手动检查…实际上,在我调用tpl任务内部的公共静态函数时发生了这种情况。使用try-catch可以解决这个问题吗?我真的需要创建另一个任务并等待它吗?感谢+1提到需要调用
SetObserved
on
unobservedtaskeexceptioneventargs
。为了增加娱乐性,在一个名为您选择的四个字母单词的类中使用静态存根方法
Off
,并将其用于您的“一网打尽”连续剧。有助于克服这个特殊异常带来的一些压抑的沮丧情绪。@MonsterMMORPG是的-你基本上必须在某个地方捕获或处理异常。只要你在某个地方处理它,你的核心问题就会消失。难道任务不可能在调用ContinueWith之前抛出异常吗?@TimSylvester框架仍然会在continuation中映射它,即使它发生在“之前”续页随附重要注意事项:这仅适用于
.Net 4.0
。默认情况下,在
.net 4.5
中更改了异常处理,以不中断应用程序。在中查看更多信息