未处理的异常发生在处理异常之后



这个主题来自我之前的问题:如何在Windows事件查看器中删除和创建日志

我创建了wpf应用程序。我用三种方式捕捉未处理的异常:

public partial class App : Application
{
public App()
{
DispatcherUnhandledException += App_DispatcherUnhandledException;
Dispatcher.UnhandledException += Dispatcher_UnhandledException;
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
}
private void Dispatcher_UnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
}
private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
}
}

我正在创建这样的异常:

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
throw new Exception("Test exception");
}
}

在执行方法(Dispatcher_UnhandledExceptionCurrentDomain_UnhandledExceptionApp_DispatcherUnhandledException(之后,此异常仍在抛出。Windows事件查看器正在创建类似的日志

描述:进程由于未处理的异常而终止。异常信息:System.InvalidOperationException位于System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(System.Data.Common.DbConnection,System.Threading.Tasks.TaskCompletionSource1<System.Data.ProviderBase.DbConnectionInternal>, System.Data.Common.DbConnectionOptions, System.Data.ProviderBase.DbConnectionInternal, System.Data.ProviderBase.DbConnectionInternal ByRef) at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(System.Data.Common.DbConnection, System.Data.ProviderBase.DbConnectionFactory, System.Threading.Tasks.TaskCompletionSource1

在处理程序方法中,您需要告诉.NET您处理了异常。否则,它仍然会杀死应用程序。可以使用DispatcherUnhandledExceptionEventArgs对象的Handled属性来执行此操作。

因此,如果您决定在出现异常的情况下继续应用程序,请将其设置为true:

private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
e.Handled = true; //let's continue and see if anything explodes
}

也就是说,您仍然应该(尽可能多地(处理可能发生的异常。以你举的例子为例,它看起来像是一个网络连接问题。如果你在创建连接时发现了异常,你可以告诉用户一些更具体的信息,比如"我无法连接到数据库。你的网络在工作吗?"而如果你依靠这个来捕捉这种错误,你只能重复异常消息,这对用户来说通常没有意义。

这应作为故障保护的最后手段。它不应该取代在整个代码中捕获异常。

这样的全局错误处理应该会关闭应用程序。你有一个来自其他地方的异常,应用程序处于某种未知状态。

如果你接受了错误,只是让用户继续,那么你就无法知道会发生什么。

"标准"方法是记录错误,然后用关闭

Application.Current.Shutdown();

最新更新