C#来自另一个线程的未处理异常继续循环
我有一条非常简单的线。Thread对象所做的唯一事情就是C#来自另一个线程的未处理异常继续循环,c#,multithreading,visual-studio-2010,infinite-loop,unhandled-exception,C#,Multithreading,Visual Studio 2010,Infinite Loop,Unhandled Exception,我有一条非常简单的线。Thread对象所做的唯一事情就是抛出新异常()。之所以这样做,是因为我需要测试在应用程序的单独线程中发生异常时会发生什么。我已经用一个“真实”运行时异常测试了这个问题,我的问题也是一样的 在调用线程之前,我要做的是: AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException; Application.Current.DispatcherUnhandledException
抛出新异常()代码>。之所以这样做,是因为我需要测试在应用程序的单独线程中发生异常时会发生什么。我已经用一个“真实”运行时异常测试了这个问题,我的问题也是一样的
在调用线程之前,我要做的是:
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
Application.Current.DispatcherUnhandledException += CurrentOnDispatcherUnhandledException;
//To handle exceptions in another thread
private void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
{
//Do nothing ignore exception
}
//To handle all exceptions in main thread
private static void CurrentOnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs dispatcherUnhandledExceptionEventArgs)
{
dispatcherUnhandledExceptionEventArgs.Handled = true;
}
当此线程确实抛出异常时,它会像应该的那样首先命中CurrentDomainOnUnhandledException
,然后不会命中CurrentOnDispatcherUnhandledException
。紧接着CurrentDomainOnUnhandledException
堆栈然后移回抛出异常的线程,并再次抛出异常,执行同一行。它从不停止这样做。这基本上是一个永无止境的循环,我不明白为什么
UnhandledExceptionEventArgs没有要设置的属性,也就是说我们已经处理了异常,我很确定这是问题的一部分
我做错了什么,如何在此线程中捕获此未处理的异常,并让线程继续执行(首选)或中止/终止线程(非首选),以便它不会继续执行抛出新异常行
我已经用debug和release测试了这一点(确保release上的debug info设置为none),但这在两个版本中都会发生,异常会一次又一次地发生
提前谢谢,我只是被难住了,不知道它为什么这么做
当该线程确实抛出异常时,它会像应该的那样首先命中CurrentDomainOnUnhandledException,然后不会命中CurrentOnDispatcherUnhandledException。紧接着CurrentDomainOnUnhandledException之后,堆栈将移回抛出异常的线程,并再次抛出异常,执行同一行。它从不停止这样做。这基本上是一个永无止境的循环,我不明白为什么
你从未处理过这个异常。您刚刚返回到最初出现故障的代码。假设代码执行以下操作:
i = 1 / 0;
foo(i);
假设您捕捉到零除错误,但在处理程序中,您只返回。那么,你希望发生什么?代码遇到了一个致命错误,无法继续执行,您没有采取任何措施来修复它。i
应该包含什么值
本质上,不要试图捕捉异常,除非是作为抛出异常的代码设计的一部分。这是没有道理的,不管你的外在问题是什么,可能有一个明智的方法去做
但是如果一个线程严重失败,它的进程也会严重失败。这就是线程的本质——没有隔离。考虑:
获取锁
修改某个对象
释放锁
如果在步骤2的中途抛出异常,会发生什么情况?如果异常处理程序没有释放锁,那么下一个尝试获取锁的线程将永远等待。如果您的异常处理程序确实释放了锁,那么获取锁的下一个线程将访问部分修改过的对象,并且可能处于不一致的状态。因此,异常处理程序必须做出智能决策,了解引发异常的代码,以及在释放引发异常时持有的锁之前要做什么
如果要捕获异常,必须找出根本问题并修复它。通常,只有完全理解引发异常的代码,才能执行此操作。没有通用的方法来执行此操作,因为没有通用的方法来修复可能损坏的对象
好的,那么如何杀死CurrentDomainOnUnhandledException中的线程,使其停止循环异常
一般来说,这不是你想做的。如果线程持有锁怎么办?如果线程分配了它需要释放的内存呢
如果需要这种隔离,请使用进程,而不是线程。在发生未捕获异常后,线程无法继续执行。它将运行什么代码?引发异常的全部目的是专门防止下一行代码执行。这就像在代码中出现return
后试图留在函数中一样。我不知道你为什么认为你需要这么做,但我很确定你是从某个根本的误解出发的。你让我信服了,没有办法弥补。这将是一个非常严重的CLR错误。请记录您使用的.NET版本,并发布启动线程和引发异常的代码,以便每个人都可以在自己的机器上重新编程。