我有一个为.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处理程序是不会捕获该异常?或者它会导致程序死亡而不报告任何内容?
答案 0 :(得分:7)
我的问题是,如果catch块中发生异常,如果没有其他异常处理程序来捕获错误,那么上层的Unhandled Exception处理程序是不会捕获该异常?或者它会导致程序死亡而不报告任何内容?
异常将向上传播,并且应由未处理的异常处理程序捕获。
话虽如此,但有些例外情况不会被发现,例如StackOverflowException
。异常块(或DB提供程序......?)中的代码也可能以一种不允许异常处理的方式终止进程(即:调用Environment.Exit
或者同样糟糕的东西)。工作
答案 1 :(得分:3)
简而言之是未处理的异常
请记住,至少有两个地方应该记录未处理的例外情况。 应用程序 Application.DispatcherUnhandledException 处理程序的 AppDomain UnhandledException 和 EACH 。
如果你没有抓住这些,申请将会终止。
还要注意,自.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.
}
需要注意的是,如果您最终遇到任何这些“全局”异常处理程序,您的应用程序处于未知但已损坏的状态,唯一有效的做法是记录问题并退出/重新启动应用;即使您仍然可以让应用程序运行,此时您无法恢复。