一般情况下我们业务代码不需要自己捕获异常,因为目前我们常用框架都会自行处理异常,但是有些情况下需要自己处理异常,否则未处理的异常抛出会导致程序崩溃退出。
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代码等不安全代码,大部分时候也时无法捕获,如果它们引起异常也很难捕获。
完