来自另一个线程的C#UnhandledException保持循环

时间:2012-09-01 04:58:35

标签: 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例外情况。

我已经通过调试和发布测试了这一点(确保发布时的调试信息设置为无),这两种版本中都会发生这种情况,异常会一次又一次地发生。

在此先感谢,我很难过,并且不知道为什么会这样做。

1 个答案:

答案 0 :(得分:1)

  

当这个线程抛出一个异常时,它首先按照应该的那样命中CurrentDomainOnUnhandledException,然后它不会触及CurrentOnDispatcherUnhandledException。在CurrentDomainOnUnhandledException之后,然后堆栈移回到Thread,在那里它抛出异常并再次抛出它,执行相同的行。它永远不会停止这样做。它基本上是一个永无止境的循环,我无法弄清楚原因。

你从未处理过这个例外。您刚刚返回到与第一个出现故障相同的代码。说代码执行此操作:

i = 1 / 0;
foo(i);

并且说你通过零错误捕获除法,但在处理程序中,除了返回之外什么都不做。那么,你期望会发生什么?代码遇到致命错误,无法取得进一步的进展,你没有采取任何措施来解决它。 i应包含什么价值?!

基本上,不要尝试捕获异常,除非作为抛出它们的代码设计的一部分。它只是没有意义,无论你的外在问题是什么,都可能有一种合理的方法。

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

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

    如果要捕获异常,必须找出底层问题是什么并修复它。通常,只有在完全理解引发异常的代码时才能执行此操作。没有通用的方法,因为没有通用的方法来修复潜在的损坏对象。

      

    好的,那我怎么杀掉CurrentDomainOnUnhandledException中的线程所以它停止循环异常呢?

    一般情况下,这不是你想要做的。如果该线程持有锁怎么办?如果该线程分配了需要释放的内存怎么办?

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