控制台应用程序未被未处理的任务异常拆除

时间:2016-06-14 15:28:32

标签: c# task-parallel-library

我试图弄清楚为什么我的控制台应用程序没有被未处理的任务异常拆除。我所做的只是创建一个任务,我立即抛出异常。最后我强迫GC。在第一个例子中,我有一个TaskScheduler.UnobservedTaskException事件的处理程序,我可以看到异常得到处理。

 static async Task ThrowsException()
 {
     Console.WriteLine("Throwing!");
     throw new Exception("Test exception");
}

static void Main(string[] args)
{
    TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
    ThrowsException();
    Console.WriteLine("Collecting garbage.");
    GC.Collect();
    GC.WaitForPendingFinalizers();
    Console.WriteLine("Done collecting garbage.");
    Console.ReadKey();
}

static void TaskScheduler_UnobservedTaskException(object sender,
   UnobservedTaskExceptionEventArgs e)
{
    Console.WriteLine("Unobserved task exception occured in finalizer.");
    Console.WriteLine(e.Exception.InnerException.Message);
}

输出:

Throwing!
Collecting garbage.
Unobserved task exception occured in finalizer.
Test exception
Done collecting garbage.

但如果我注释掉TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException行,程序仍会运行完成。在这种情况下,输出是:

Throwing!
Collecting garbage.
Done collecting garbage.

为什么在这种情况下应用程序崩溃?

2 个答案:

答案 0 :(得分:4)

不会从未观察到的任务异常崩溃程序异常是对.NET 4.5所做的更改,请参阅remarks section of the MSDN for the event。如果您希望程序具有.NET 4.5之前的行为并导致它崩溃,则需要输入app.config

<configuration> 
   <runtime> 
      <ThrowUnobservedTaskExceptions enabled="true"/> 
   </runtime> 
</configuration>

这会带回旧的行为。

答案 1 :(得分:0)

ThrowsException是一个异步方法,因此除非你等待这个方法,否则将吞下异常。
我假设您需要像这样调用此方法:

ThrowsException.Wait();

甚至可以捕获异常:

try
{
    ThrowsException().Wait();
}
catch (AggregateException e)
{
    // Do something
}

此外,阅读以下内容将有助于您了解它为何不会导致您的应用程序崩溃:TaskScheduler.UnobservedTaskException Event