我使用的是.NET 1.1 compability模式未处理的异常处理。问题是,当LegacyUnhandledExceptionPolicy设置为1(这是我想要什么),我不能赶上和吞咽ThreadAbortException。
I'm using .NET 1.1 compability mode for unhandled exception handling. The problem is that when LegacyUnhandledExceptionPolicy is set to "1" (which is what I want), I cannot catch and swallow ThreadAbortException.
示例code:
App.config中:
App.config:
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="1"/>
</runtime>
</configuration>
code:
Code:
class Program {
static void Main(string[] args) {
AppDomain.CurrentDomain.UnhandledException += _onBackgroundThreadCrash;
var t = new Thread(_worker) { IsBackground = true };
t.Start();
Thread.Sleep(1000);
t.Abort();
Console.ReadLine();
}
private static void _worker() {
try {
while (true);
} catch (ThreadAbortException) {
// expected thread exit, don't rethrow
}
}
private static void _onBackgroundThreadCrash(object sender, UnhandledExceptionEventArgs e) {
Console.WriteLine(e.ExceptionObject as Exception);
}
}
在传统的异常处理是0(OFF),上述code燕子ThreadAbortException queitly,符合市场预期。
When legacy exceptions handling is "0" (OFF), the above code swallows ThreadAbortException queitly, as expected.
但是,在原有的异常处理是1上面的code打印ThreadAbortException安慰,这不是我所期望的。
But, when legacy exceptions handling is "1" the above code prints ThreadAbortException to console, which is not what I expect.
任何想法?
感谢。
您不能赶上一个ThreadAbortException,它总是抓后重新提出。有两种基本的解决方案,您的问题。
You cannot catch a ThreadAbortException, it is always re-raised after catching it. There are two basic solutions to your problem.
第一个是您重置中止请求:
First one is that you reset the abort request:
catch (ThreadAbortException) {
// expected thread abort request, reset it and exit thread
Thread.ResetAbort();
}
第二个是要解决当您启用旧的异常处理这种情况发生的另一件事。该AppDomain.UnhandledException事件现在也提出了非致命异常。写下您的异常处理程序是这样的:
Second one is to address the other thing that happens when you enable legacy exception handling. The AppDomain.UnhandledException event is now also raised for non-fatal exceptions. Write your exception handler like this:
private static void _onBackgroundThreadCrash(object sender, UnhandledExceptionEventArgs e) {
if (e.IsTerminating) {
Console.WriteLine(e.ExceptionObject as Exception);
}
}
我要推荐的第一个解决方案,你真的不想未处理的终止线程没有留下任何痕迹,在所有异常。
I'd have to recommend the first solution, you really don't want unhandled exceptions that terminate a thread to leave no trace at all.