dotnet未捕获异常导致系统崩溃问题
一般情况下我们业务代码不需要自己捕获异常,因为目前我们常用框架都会自行处理异常,但是有些情况下需要自己处理异常,否则未处理的异常抛出会导致程序崩溃退出。
1.全局异常捕获
// 1. AppDomain 未处理异常
AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
{
var exception = e.ExceptionObject as Exception;
LogException(exception, "UnhandledException");
if (e.IsTerminating)
{
// 进程即将终止
EmergencyShutdown();
}
};
// 2. Task 未观察异常 (.NET 4.0+)
TaskScheduler.UnobservedTaskException += (sender, e) =>
{
LogException(e.Exception, "UnobservedTaskException");
e.SetObserved(); // 防止进程崩溃
};
// 3. Windows Forms
if (Application.MessageLoop)
{
Application.ThreadException += (sender, e) =>
{
LogException(e.ception, "ThreadException");
};
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
}
// 4. WPF
Dispatcher.CurrentDispatcher.UnhandledException += (sender, e) =>
{
LogException(e.Exception, "DispatcherUnhandledException");
e.Handled = true; // 阻止进程崩溃
};
// 5. ASP.NET Core
// 在 Program.cs 中使用 UseExceptionHandler 中间件
2.Timer异常 和 异步void方法异常
定时器的事件方法中的代码抛出来的异常,无法被全局异常捕获,同样异步void方法异常也是的,需要自行捕获异常。
public class SafeTimer
{
private readonly Timer _timer;
public SafeTimer()
{
_timer = new Timer(OnTimerCallback);
}
private void OnTimerCallback(object state)
{
try
{
// 业务逻辑
}
catch (Exception ex)
{
// 记录日志,通知主线程
LogException(ex);
}
}
}
3.StackOverflowException和OutOfMemoryException
这两个异常业务无法捕获的,因为它们发生时,程序以及没有办法在执行如何代码了,只能靠上个文章中说的崩溃自动收集dump,然后去分析dump找出问题。
还有其他比如调用c代码等不安全代码,大部分时候也时无法捕获,如果它们引起异常也很难捕获。
完
作者:Rick Carter
出处:http://pains.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
浙公网安备 33010602011771号