任务和异常沉默

Sle*_*idi 18 c# multithreading exception-handling task

为什么在任务中抛出的异常是静默异常,你永远不知道是否抛出了某个异常

try
{

 Task task = new Task(
  () => {
          throw null;
        }
        );
  task.Start();
 }
 catch
 {
  Console.WriteLine("Exception");
 }  
Run Code Online (Sandbox Code Playgroud)

程序在完全沉默中成功运行!线程的行为是不同的

try
{

 Thread thread = new Thread(
  () => {
          throw null;
        }
        );
  thread .Start();
 }
 catch
 {
  Console.WriteLine("Exception");
 }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,将抛出空指针异常.有什么不同?

Mar*_*ell 16

该场景的行为取决于您拥有的框架; 在4.0中,你实际上需要小心 - 如果你不处理TaskScheduler.UnobservedTaskException,它将在以后收集/完成时出错,并将杀死你的进程.

TaskScheduler.UnobservedTaskException += (sender, args) =>
{
    Trace.WriteLine(args.Exception.Message); // somebody forgot to check!
    args.SetObserved();
};
Run Code Online (Sandbox Code Playgroud)

这改变了4.5,IIRC.

要检查的结果Task可能会失败,你可以注册一个延续-即呼叫ContinueWith和检查结果的异常.或者,访问.Result任务(也会隐式执行Wait())将重新显示发生的异常.观察任务的结果是很好的,因为它清除了终结标志,这意味着它可以更便宜地收集.


Ric*_*lly 5

不,任务不是线程.任务代表高级抽象 - 它们是本质上可并行化的工作单元.线程运行工作单元.

在您的第一个示例中,您创建一个工作单元,然后告诉它自己运行(它是如何执行任务的实现细节).而在您的第二个示例中,您明确地安排了一个工作单元(它将以与Task的实现不同的方式出现).

  • @sleimanjneidi任务将存储查询任务时的异常.在一个线程中没有固有的异常处理,它将向上传播,直到捕获到异常. (2认同)