来自另一个线程的 C# UnhandledException 不断循环

标签 c# multithreading visual-studio-2010 infinite-loop unhandled-exception

我有一个非常简单的线程。 Thread 对象所做的唯一事情就是throw new Exception();。我这样做的原因是因为我需要测试如果异常发生在我的应用程序的单独线程中会发生什么。我已经用“真实的”运行时异常对此进行了测试,我的问题是一样的。

在调用线程之前我做的是:

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 没有要设置的属性,也就是说我们已经处理了异常,我很确定这是问题的一部分。

我做错了什么,我如何在这个线程中捕获这个UnhandledException,让线程继续执行(首选)或者中止/杀死线程(不首选)使其不继续执行throw new异常(exception)行。

我已经用调试和发布测试了这个(确保发布时的调试信息设置为无),这在两个版本中仍然发生,异常继续一遍又一遍地发生。

在此先感谢,我只是被难住了,不知道为什么会这样。

最佳答案

When this thread does throw a exception it first hits CurrentDomainOnUnhandledException like it should, and then it does not hit CurrentOnDispatcherUnhandledException. Right after CurrentDomainOnUnhandledException The stack then moves back to the Thread where it throws the exception and throws it again, executing the same line. It never stops doing this. It is basically a never ending loop and I can not figure out why.

您从未处理过异常。您刚刚返回到最初出错的代码。假设代码是这样做的:

i = 1 / 0;
foo(i);

假设您捕捉到被零除的错误,但是在处理程序中,除了返回之外什么都不做。那么,你希望发生什么?代码遇到了一个 fatal error ,使进一步的进展变得不可能,而你没有采取任何措施来修复它。 i 应该包含什么值?!

基本上,不要 try catch 异常,除非是作为抛出异常的代码设计的一部分。它只是没有意义,无论您的外部问题是什么,都可能有一个明智的方法来做到这一点。

但是如果一个线程严重失败,它的进程也会严重失败。这就是线程的本质——没有隔离。考虑:

  1. 获取锁
  2. 修改一些对象
  3. 释放锁

如果在第 2 步中途抛出异常会怎样?如果您的异常处理程序不释放锁,下一个尝试获取它的线程将永远等待。如果您的异常处理程序确实释放了锁,那么下一个获取它的线程将访问一个被部分修改并且可能处于不一致状态的对象。因此,异常处理程序必须做出明智的决定,了解引发异常的代码,以及在释放引发异常时持有的任何锁之前要做什么。

如果您要捕获异常,您必须找出潜在的问题并修复它。一般来说,只有完全理解抛出异常的代码才能这样做。没有通用的方法来执行此操作,因为没有通用的方法来修复可能损坏的对象。

Ok, then how do I kill the thread in CurrentDomainOnUnhandledException so it stops looping the exception?

通常这不是您想要做的。如果该线程持有锁怎么办?如果该线程分配了需要释放的内存怎么办?

如果您需要这种隔离,请使用进程,而不是线程。

关于来自另一个线程的 C# UnhandledException 不断循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12225011/

相关文章:

c# - Visual Studio 中的安装项目创建的 setup.exe 文件有什么意义吗?

c# - 指导我在 asp.net 中做 This Timer Application

c# - 在 finally block 上使用未分配的局部变量

java - 我可以在 Scala 中将本地 var 作为 Volatile,因为在 Java 中这是不可能的吗?

c# - 如何在 Microsoft Visual C# 2010 Express 中部署项目?

c# - 使用 savefileDialog 选择文件夹路径

c# - 在按钮 onclick 上调用 blockUI

java - 发出请求时 JAX-RS 'endpoint' 的行为如何?

multithreading - 延长线程变量的生命周期

c# - 在 C# 中搜索文件的更好方法