为什么后台线程中未处理的异常不会导致应用程序域崩溃?

Bop*_*Bop 15 .net c# multithreading delegates exception-handling

我完全不解.如果在我从未测试过的线程中存在未捕获的异常,我非常确定.NET会关闭整个应用程序域.

但是我只是尝试了下面的代码并且它没有失败......任何人都可以解释为什么?

(在.NET 4和3.5中尝试过)

static void Main(string[] args)
{
    Console.WriteLine("Main thread {0}", Thread.CurrentThread.ManagedThreadId);

    Action a = new Action(() =>
    {
        Console.WriteLine("Background thread {0}", Thread.CurrentThread.ManagedThreadId);

        throw new ApplicationException("test exception");
    });

    a.BeginInvoke(null, null);

    Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)

Jal*_*aid 9

发生这种情况是因为内部BeginInvoke使用ThreadPool以及ThreadPool任何未加扰的异常将导致静默失败.但是,如果您使用,a.EndInvoke那么unhadled异常将抛出该EndInvoke方法.

注意:如上所述João Angelo,使用ThreadPool直接"喜欢ThreadPool.QueueUserWorkItemsUnsafeQueueUserWorkItem"的方法会在2.0及更高版本处抛出异常.

  • -1:您的回答还表明,使用抛出异常的方法调用"ThreadPool.QueueUserWorkItem"将导致框架使用该异常,而在2.0版及更高版本中则不然. (2认同)

Jon*_*ant 6

从MSDN上的托管线程中的例外:

在.NET Framework 2.0版中,公共语言运行库允许线程中大多数未处理的异常自然地进行.在大多数情况下,这意味着未处理的异常会导致应用程序终止.

这是.NET Framework版本1.0和1.1的重大变化,它为许多未处理的异常提供了支持 - 例如,线程池线程中的未处理异常.请参阅本主题后面的"从先前版本更改".

作为临时兼容性措施,管理员可以在应用程序配置文件的部分中放置兼容性标志.这会导致公共语言运行库恢复到版本1.0和1.1的行为.

<legacyUnhandledExceptionPolicy enabled="1"/>
Run Code Online (Sandbox Code Playgroud)

  • @Bobb:对于那些试图免费帮助你的陌生人,你是如何回应批评的?这对你有什么影响? (19认同)
  • 我理解了这个问题,我告诉你官方指导是什么,给你一些可能的原因(框架版本,配置设置),并进一步阅读以了解发生了什么:) (6认同)