What does this mean and how to resolve it?
这意味着什么?如何解决?
I am using TPL tasks.
我正在使用TPL任务。
The whole error
整个错误
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 rethrown by the finalizer thread.
任务的异常不是通过等待任务或访问其异常属性来观察的。结果,未观察到的异常被终结器线程重新抛出。
at System.Threading.Tasks.TaskExceptionHolder.Finalize()
在System.Threading.Tasks.TaskExceptionHolder.Finalize()
mscorlib
mscorlib
3 个解决方案
#1
130
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.
如果您创建了一个任务,并且从来没有调用Task . wait()或尝试检索任务
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:
有了以上这些,你就可以防止任何任务撕毁app,并通过以下方式记录下来:
Task.Factory.StartNew( () =>
{
// Do your work...
}).LogExceptions();
Alternatively, you can subscribe to the TaskScheduler.UnobservedTaskException and handle it there.
或者,您可以订阅TaskScheduler。UnobservedTaskException并在那里进行处理。
#2
32
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 theTask
in the parameter) - 直接处理任务失败(使用ContinueWith(…)来订阅,并检查.IsFaulted和.Exception在参数中的任务)
- handle the
TaskScheduler.UnobservedTaskException
event, and mark it observed (calle.SetObserved()
after logging the error) - 处理TaskScheduler。UnobservedTaskException事件,并标记它被观察(记录错误后调用e. setobserve ())))
#3
-13
Try this one:
试试这个:
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;
}
#1
130
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.
如果您创建了一个任务,并且从来没有调用Task . wait()或尝试检索任务
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:
有了以上这些,你就可以防止任何任务撕毁app,并通过以下方式记录下来:
Task.Factory.StartNew( () =>
{
// Do your work...
}).LogExceptions();
Alternatively, you can subscribe to the TaskScheduler.UnobservedTaskException and handle it there.
或者,您可以订阅TaskScheduler。UnobservedTaskException并在那里进行处理。
#2
32
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 theTask
in the parameter) - 直接处理任务失败(使用ContinueWith(…)来订阅,并检查.IsFaulted和.Exception在参数中的任务)
- handle the
TaskScheduler.UnobservedTaskException
event, and mark it observed (calle.SetObserved()
after logging the error) - 处理TaskScheduler。UnobservedTaskException事件,并标记它被观察(记录错误后调用e. setobserve ())))
#3
-13
Try this one:
试试这个:
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;
}