通过等待任务或访问其 Exception 属性都没有观察到任务的异常。因此,未被观察到的例外是

这意味着什么? 如何解决这个问题?

我正在使用 TPL 任务。

整个错误

通过等待任务或访问其 Exception 属性都没有观察到任务的异常。因此,终结器线程将重新引发未观察到的异常。

在系统。线程。任务。 TaskExceptionHolder。 Finalize ()

米斯科利布

61351 次浏览

If you create a Task, and you don't ever call task.Wait() or try to retrieve the result of a Task<T>, when the task is collected by the garbage collector, it will tear down your application during finalization. For details, see MSDN's page on Exception Handling in the TPL.

The best option here is to "handle" the exception. This can be done via a continuation - you can attach a continuation to the task, and log/swallow/etc the exception that occurs. This provides a clean way to log task exceptions, and can be written as a simple extension method, ie:

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

With the above, you can prevent any task from tearing down the app, and logging it, via:

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

Alternatively, you can subscribe to the TaskScheduler.UnobservedTaskException and handle it there.

Sure; it means a Task got finalized after being left to garbage collection, but the task itself failed. There are two fixes:

  • handle the tasks fail directly (use ContinueWith(...) to subscribe, and check .IsFaulted and .Exception on the Task in the parameter)
  • handle the TaskScheduler.UnobservedTaskException event, and mark it observed (call e.SetObserved() after logging the error)