2

我有一个为 .NET 4 Full Framework 编写的 WPF 应用程序。该应用程序使用 SQL Anywhere 作为其数据库。我的应用程序有一个未处理的异常处理程序,它总是将错误记录到程序的自定义事件日志中。然后它向用户显示错误消息。该程序还会在即将执行某项操作时向事件日志发送消息,以便更轻松地进行调试。

该应用程序安装在运行 Windows 7 并具有 8 GB RAM 的用户笔记本电脑上。在本机上启动时,会显示启动画面,然后显示程序的主窗口。绘制后不到一秒钟,程序就死了。没有显示错误消息。

检查事件日志显示程序写入的最后一条消息是它正在检查数据库中是否存在用户。没有错误消息。

显示的最后一条消息后面的代码是对执行某些参数检查然后执行以下 EF 查询的方法的调用:

LPRCore.CarSystem.User user = null;

IQueryable<User> query = from u in context.Users
                         from m in context.Members.Where( m => m.UserId == u.UserId )
                                                  .DefaultIfEmpty()
                         where u.LoweredUserName == userName.ToLower() && m == null
                         select u;
try {
    user = query.SingleOrDefault();

} catch ( Exception ex ) {
    ....
}

我不知道是否曾经调用过 catch 块中的代码。我的怀疑是它被调用并且那里发生了异常。

我的问题是,如果catch块中发生异常,如果没有其他异常处理程序来捕获错误,那么上层的Unhandled Exception处理程序不会捕获该异常吗?或者它会导致程序在没有报告任何内容的情况下死掉?

4

2 回答 2

7

我的问题是,如果catch块中发生异常,如果没有其他异常处理程序来捕获错误,那么上层的Unhandled Exception处理程序不会捕获该异常吗?或者它会导致程序在没有报告任何内容的情况下死掉?

异常将向上传播,并且应该被未处理的异常处理程序捕获。

话虽如此,一些异常不会被捕获,例如StackOverflowException. 异常块(或数据库提供程序...?)中的代码也可能以Environment.Exit不允许异常处理工作的方式终止进程(即:调用或其他类似的东西)。

于 2013-09-27T20:59:59.217 回答
3

简而言之,一个未处理的异常

请记住,至少有 2 个地方应该记录未处理的异常。Application.DispatcherUnhandledException和应用程序的AppDomain UnhandledException处理程序的每个

如果您没有抓住这些,应用程序将终止。

另请注意,由于 .NET 2.0 线程中未处理的异常传播到应用程序,导致它终止(不是线程的应用程序)。在 .NET 1.1 中,线程只是悄悄地死掉了。

从 .NET Framework 2.0 版开始,公共语言运行时允许线程中大多数未处理的异常自然地进行。在大多数情况下,这意味着未处理的异常会导致应用程序终止。

托管线程中的异常

Application 对象的 ThreadException 处理程序似乎只捕获从应用程序主线程向上传播的异常(或者更准确地说,可能是在应用程序调度程序线程中引发的异常)。其他一切似乎都出现在应用程序域的 UnhandledException 处理程序上。

因此,除了 Application.UnhandledException 处理程序之外,添加 domain.UnhandledException 如下:

static void Main(string[] args)
{
    Application.ThreadException += ApplicationThreadException;


    AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    // Log exception here and exit application, you can't recover now.
}

需要注意的是,如果您最终遇到任何这些“全局”异常处理程序,则您的应用程序处于未知但已损坏的状态,唯一有效的做法是记录问题并退出/重新启动应用程序;此时您无法恢复,即使您仍然可以让应用程序运行。

于 2013-09-27T21:11:29.387 回答