gpt4 book ai didi

c# - 任务未处理的异常

转载 作者:可可西里 更新时间:2023-11-01 08:16:42 27 4
gpt4 key购买 nike

我试图了解在任务对象中抛出且从未处理过的异常发生了什么。

在 MSDN 上它说:

If you do not wait on a task that propagates an exception, or access its Exception property, the exception is escalated according to the .NET exception policy when the task is garbage-collected.

所以我不太明白这些异常会以何种方式影响程序流程。我认为这些异常一旦被垃圾收集就应该中断执行。但我无法设计这种行为。在以下代码段中,抛出的异常未显示。

// Do something ...
Task.Run (()=> {throw new Exception("Exception in the task!");});
// Do something else

谁能解释一下如何处理未处理的任务异常以及它们如何影响程序流程。

最佳答案

您描述的是 .NET 4 中的行为,但您很难强制执行垃圾回收并实际观察到该行为。以下引自Stephen Toub's excelent write-up关于这个主题应该更清楚:

Tasks keep track of whether an unhandled exception has been“observed.” In this context, “observed” means that code has joinedwith the Task in some fashion in order to at least be made aware ofthe exception. This could be calling Wait/WaitAll on the Task. Itcould be checking the Task’s Exception property after the Task hascompleted. Or it could be using a Task’s Result property.If a Task sees that its exception has been observed in some manner,life is good. If, however, all references to a Task are removed(making the Task available for garbage collection), and if itsexception hasn’t yet been observed, the Task knows that its exceptionwill never be observed. In such a case, the Task takes advantage offinalization, and uses a helper object to propagate the unhandledexception on the finalizer thread. With the behavior describedearlier, that exception on the finalizer thread will go unhandled andinvoke the default unhandled exception logic, which is to log theissue and crash the process.

他还建议了两种有用的扩展方法来处理“即发即弃”任务中的异常:一种忽略异常,另一种立即使进程崩溃:

public static Task IgnoreExceptions(this Task task)
{
task.ContinueWith(c => { var ignored = c.Exception; },
TaskContinuationOptions.OnlyOnFaulted |
TaskContinuationOptions.ExecuteSynchronously |
TaskContinuationOptions.DetachedFromParent);
return task;
}

public static Task FailFastOnException(this Task task)
{
task.ContinueWith(c => Environment.FailFast(“Task faulted”, c.Exception),
TaskContinuationOptions.OnlyOnFaulted |
TaskContinuationOptions.ExecuteSynchronously |
TaskContinuationOptions.DetachedFromParent);
return task;
}

在 .NET 4.5 中默认行为已更改。同样,引自 another Stephen Toub's post on the subject (感谢 mike z 在评论中引起我的注意):

To make it easier for developers to write asynchronous code based onTasks, .NET 4.5 changes the default exception behavior for unobservedexceptions. While unobserved exceptions will still cause theUnobservedTaskException event to be raised (not doing so would be abreaking change), the process will not crash by default. Rather, theexception will end up getting eaten after the event is raised,regardless of whether an event handler observes the exception. Thisbehavior can be configured, though.

关于c# - 任务未处理的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21648094/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com