lun*_*ain 42 .net c# exception
我可以连接AppDomain.CurrentDomain.UnhandledException从后台线程记录异常,但是如何阻止它们终止运行时?
小智 39
首先,你真的应该尽量不在后台线程中抛出异常 - 而不是处理异常.如果您控制代理的运行方式,请将其封装在try catch块中,并找到将异常信息传递回主线程的方法(如果您显式调用BeginInvoke,则使用EndInvoke,或者通过更新某些共享状态).
忽略未处理的异常可能很危险.如果你有一个真正的不可处理的异常(想到OutOfMemoryException),你无论如何都无法做到,你的过程基本上就注定了.
回到.Net 1.1,后台线程中的未处理异常将被抛到无处,主线程很乐意继续.这可能会产生令人讨厌的反响.所以在.Net 2.0中,这种行为发生了变化.
现在,在一个不是主线程的线程中抛出的未处理异常将终止该进程.您可能会收到此通知(通过在AppDomain上订阅该事件),但该过程仍然会死亡.
由于这可能不方便(当你不知道将在线程中运行什么并且你不完全确定它被正确保护,并且你的主线程必须具有弹性)时,有一种解决方法.它旨在作为遗留设置(意思是,强烈建议您确保没有杂散线程),但您可以通过这种方式强制执行前一种行为:
只需将此设置添加到您的服务/应用程序/任何配置文件:
<configuration>
<runtime>
<!-- the following setting prevents the host from closing when an unhandled exception is thrown -->
<legacyUnhandledExceptionPolicy enabled="1" />
</runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)
但它似乎不适用于ASP.NET.
有关更多信息(以及在即将发布的CLR版本中可能不支持此设置的巨大警告),请参阅http://msdn.microsoft.com/en-us/library/ms228965.aspx
保持简短的回答,是的,您确实可以防止运行时终止。
这是解决方法的演示:
class Program
{
void Run()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Console.WriteLine("Press enter to exit.");
do
{
(new Thread(delegate()
{
throw new ArgumentException("ha-ha");
})).Start();
} while (Console.ReadLine().Trim().ToLowerInvariant() == "x");
Console.WriteLine("last good-bye");
}
int r = 0;
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Interlocked.Increment(ref r);
Console.WriteLine("handled. {0}", r);
Console.WriteLine("Terminating " + e.IsTerminating.ToString());
Thread.CurrentThread.IsBackground = true;
Thread.CurrentThread.Name = "Dead thread";
while (true)
Thread.Sleep(TimeSpan.FromHours(1));
//Process.GetCurrentProcess().Kill();
}
static void Main(string[] args)
{
Console.WriteLine("...");
(new Program()).Run();
}
}
Run Code Online (Sandbox Code Playgroud)
本质上,您只是没有让运行时显示“...程序已停止工作”对话框。
如果您需要记录异常并静默退出,您可以调用Process.GetCurrentProcess().Kill();
| 归档时间: |
|
| 查看次数: |
26450 次 |
| 最近记录: |