通过等待任务或访问它的Exception属性,没有观察到任务的exception。 结果,没有被察觉的例外是

这是什么意思,如何解决?

我正在使用TPL任务。

整个错误

通过等待任务或访问它的Exception属性,没有观察到任务的exception。 结果,终结者线程重新抛出了未观察到的exception。

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

mscorlib程序

如果你创build了一个Task,并且你不曾经调用task.Wait()或者试图获取Task<T>的结果,那么当垃圾收集器收集任务时,它将在定稿过程中拆除你的应用程序。 有关详细信息,请参阅TPL中“exception处理”的 MSDN页面。

这里最好的select是“处理”exception。 这可以通过延续完成 – 你可以附加一个延续任务,并logging/吞下/等发生的exception。 这提供了一个干净的方式来logging任务exception,可以写成一个简单的扩展方法,即:

 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); } 

通过以上这些,您可以防止任何任务将应用程序拆除,并通过以下方式将其logging下来:

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

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

当然; 这意味着一个Task被留在垃圾收集后被敲定,但任务本身失败。 有两个修复程序:

  • 处理任务直接失败(使用ContinueWith(...)进行预订,并在参数中检查Task中的.IsFaulted.Exception
  • 处理TaskScheduler.UnobservedTaskException事件,并将其标记为已logginge.SetObserved()logging错误后调用e.SetObserved()

试试这个:

 public static void ThrowFirstExceptionIfHappens(this Task task) { task.ContinueWith(t => { var aggException = t.Exception.Flatten(); foreach (var exception in aggException.InnerExceptions) { throw exception; // throw only first, search for solution } }, TaskContinuationOptions.OnlyOnFaulted); // not valid for multi task continuations } public static Task CreateHandledTask(Action action) { Task tsk = Task.Factory.StartNew(action); tsk.ThrowFirstExceptionIfHappens(); return tsk; }