我正在使用.NET 1.1兼容模式进行未处理的异常处理。问题是,当LegacyUnhandledExceptionPolicy设置为“1”(这是我想要的)时,我无法捕获并吞下ThreadAbortException。
示例代码:
App.config:
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="1"/>
</runtime>
</configuration>
代码:
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”(关闭)时,上面的代码将按预期方式吞下ThreadAbortException。
但是,当旧式异常处理为“1”时,以上代码将ThreadAbortException打印到控制台,这不是我期望的。
有任何想法吗?
谢谢。
最佳答案
您不能捕获ThreadAbortException,它总是在捕获后重新引发。有两种基本的解决方案来解决您的问题。
第一个是您重置中止请求:
catch (ThreadAbortException) {
// expected thread abort request, reset it and exit thread
Thread.ResetAbort();
}
第二个是解决启用旧式异常处理时发生的另一件事。现在,还会针对非严重异常引发AppDomain.UnhandledException事件。像这样编写您的异常处理程序:
private static void _onBackgroundThreadCrash(object sender, UnhandledExceptionEventArgs e) {
if (e.IsTerminating) {
Console.WriteLine(e.ExceptionObject as Exception);
}
}
我不得不推荐第一个解决方案,您真的不希望终止线程的未处理异常完全不留痕迹。