任务和异常沉默 [英] Task and exception silence
问题描述
为什么在任务中抛出的异常是静默异常,你永远不知道是否抛出了一个异常。
Why exceptions thrown within a task are silent exception and you never know if a certain exception has been thrown
try
{
Task task = new Task(
() => {
throw null;
}
);
task.Start();
}
catch
{
Console.WriteLine("Exception");
}
该程序在一个完整的沉默中成功运行!
线程的行为不同
the program run successfully in a complete silence! where the behavior of threads is different
try
{
Thread thread = new Thread(
() => {
throw null;
}
);
thread .Start();
}
catch
{
Console.WriteLine("Exception");
}
在这种情况下将抛出一个空指针异常。
有什么区别?
a null pointer exception will be thrown in this case. What is the difference?
推荐答案
这种情况的行为取决于你拥有的框架;在4.0中,您实际上需要注意 - 如果您不处理 TaskScheduler.UnobservedTaskException
,则在收集/确定后会错误 ,并且将杀死你的进程。
The behaviour of that scenario depends on what framework you have; in 4.0, you actually need to be careful - if you don't handle TaskScheduler.UnobservedTaskException
, it will error later when it gets collected/finalized, and will kill your process.
TaskScheduler.UnobservedTaskException += (sender, args) =>
{
Trace.WriteLine(args.Exception.Message); // somebody forgot to check!
args.SetObserved();
};
这个变化在4.5,IIRC。
This changes in 4.5, IIRC.
要检查任务
的结果,可能失败,您可以注册一个延续 - 即调用 ContinueWith
并检查结果的异常。或者,访问任务的 .Result
(也将执行隐式 Wait()
)将重新表达发生的例外。观察一个任务的结果是很好的,因为它清除了最终化标志,这意味着它可以更便宜地收集。
To check the outcome of a Task
that might fail, you could register a continuation - i.e. call ContinueWith
and check the result's exception. Alternatively, accessing the .Result
of the task (which would also do an implicit Wait()
) will re-surface the exception that happened. It is good to observe the result of a task, as that clears the finalization flag, meaning it can be collected more cheaply.
这篇关于任务和异常沉默的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!