来自另一个线程的C#UnhandledException不断循环 [英] C# UnhandledException from another thread keeps looping

查看:134
本文介绍了来自另一个线程的C#UnhandledException不断循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的线程. Thread对象唯一要做的是throw new Exception();.之所以这样做,是因为我需要测试如果在应用程序的单独线程中发生异常,会发生什么情况.我已经使用实时"运行时异常对此进行了测试,而我的问题是相同的.

I have a thread that is very simple. The only thing the Thread object does is throw new Exception();. The reason why I did that is because I needed to test what happens if a exception happens in a separate thread in my application. I have tested this with a "real" run time exception and my problem is the same.

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

What I do before I call the thread is:

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之后,堆栈然后移回Thread,在该线程中引发异常并再次引发异常,执行同一行.它永远不会停止这样做.这基本上是一个永无止境的循环,我不知道为什么.

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.

UnhandledExceptionEventArgs没有要设置的属性,也就是说我们已经处理了异常,我很确定这是问题的一部分.

The UnhandledExceptionEventArgs does not have a property to set, to say we have handled the exception and I am pretty sure this is part of the problem.

我在做什么错,我如何在该线程中捕获此UnhandledException,并让该线程继续执行(首选)或中止/杀死该线程(不首选),以便它不继续执行throw new例外行.

What am I doing wrong, how to I catch this UnhandledException in this thread, and let the thread continue to execute (preferred) or abort / kill the thread (not preferred) so that it does not continue to execute the throw new exception line.

我已经用debug和release测试了这一点(确保将release上的调试信息设置为none),并且在这两个版本中仍然会发生这种情况,例外情况一遍又一遍地发生.

I have tested this with debug and release (made sure debugging info on release was set to none) and this still happens in both versions, the exception continues to happen over and over again.

预先感谢,我很困惑,不知道为什么要这么做.

Thanks in advance, I am just stumped and have no idea why it does it.

推荐答案

当此线程确实引发异常时,它首先像应有的方式遇到CurrentDomainOnUnhandledException,然后又没有遇到CurrentOnDispatcherUnhandledException.在CurrentDomainOnUnhandledException之后,堆栈立即移回Thread,在该线程中引发异常并再次引发该异常,并执行同一行.它永远不会停止这样做.这基本上是一个永无止境的循环,我不知道为什么.

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.

您从未处理过异常.您刚刚回到了最初出现故障的相同代码.说代码做到这一点:

You never handled the exception. You just returned back to the very same code that faulted in the first place. Say the code does this:

i = 1 / 0;
foo(i);

并说您 catch 被零错误除,但是在处理程序中,您除了返回什么都不做.好吧,您期望发生什么?该代码遇到了致命错误,使进一步的改进变得不可能,您也无能为力. i应该包含什么值?!

And say you catch the division by zero error, but in the handler, you do nothing but return. Well, what would you expect to happen? The code encountered a fatal error that makes further progress impossible and you did nothing to fix it. What value should i contain?!

从本质上讲,除非将异常作为引发异常的代码设计的一部分,否则不要尝试捕获异常.只是没有意义,而且不管您的外部问题是什么,都有可能是一种明智的解决方法.

Essentially, don't try to catch exceptions except as part of the design of the code that throws them. It just doesn't make sense, and whatever your outer problem is, there's probably a sensible way to do it.

但是,如果线程严重失败,则其进程也将严重失败.这就是线程的本质-没有隔离.考虑:

But if a thread fails horribly, its process fails horribly. That's the nature of threads -- there's no isolation. Consider:

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

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

What happens if the exception is thrown halfway through step 2? If your exception handler don't release the lock, the next thread to try to acquire it waits forever. If your exception handler does release the lock, the next thread to acquire it will access an object that's partially modified and perhaps in an inconsistent state. So an exception handler would have to make an intelligent decision, understand the code that threw the exception, as to what to do prior to releasing any locks held when the exception was thrown.

如果您要捕获异常,则必须 找出潜在的问题并进行修复.通常,只有在完全理解引发异常的代码后才能执行此操作.没有通用的方法可以执行此操作,因为没有通用的方法可以修复可能损坏的对象.

If you're going to catch the exception, you must figure out what the underlying problem is and repair it. In general, you can only do this if you fully understand the code that threw the exception. There's no generic way to do it because there's no generic way to repair a potentially corrupt object.

好吧,那我该如何杀死CurrentDomainOnUnhandledException中的线程,使其停止循环异常?

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

通常,这不是您想要执行的操作.如果该线程持有锁怎么办?如果该线程分配了需要释放的内存怎么办?

Generally that's not what you want to do. What if that thread holds locks? What if that thread allocated memory that it needs to release?

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

If you need this kind of isolation, use processes, not threads.

这篇关于来自另一个线程的C#UnhandledException不断循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆