2013-09-27 117 views
2

我有一个为.NET 4 Full Framework编写的WPF应用程序。该应用程序使用SQL Anywhere作为其数据库。我的应用程序有一个未处理的异常处理程序,它总是将错误记录到程序的自定义事件日志中。然后它将错误消息显示给用户。该程序还会在事件日志中发送消息,以便随时进行调试。.NET程序在什么情况下会终止?

该应用程序安装在运行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块中发生异常,那么如果没有其他异常处理程序来捕获错误,上层的未处理异常处理程序是否会捕获该异常?或者它会导致程序死亡而不报告任何内容?

+0

运行连接(远程)调试器时会发生什么? – 2013-09-27 21:04:00

+1

我们还通过添加Application.ThreadException + = OnApplicationThreadException和未处理的处理程序来捕获更多。 –

+0

即时通讯假设你也想深究这个问题的底部。首先您可以检查客户端PC上的事件查看器。如果没有“好的”异常或消息,那么当应用程序退出时,您将不得不拔出Windbg并获取转储。 – wal

回答

7

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

异常会向上蔓延,应该被未处理的异常处理程序捕获。

这就是说,一些例外将不会被捕获,如StackOverflowException。异常块(或DB提供者...?)中的代码也可能终止该过程(即:调用Environment.Exit或其他类似的东西),但这种方式不允许异常处理工作。

+2

对我来说,最常见的是堆栈溢出,对于我来说,几乎每次我通过错误地实现一个基于字段的属性来完成它,比如'public object Thing {get {return Thing; }}'而不是'return thing;'...我认为代码分析能够为我抓到一些这样的东西:)。如果我是你,我的第一个检查就是执行'LoweredUserName'' –

+0

@JohnGardner当你用Release模式(优化)编译这个('get'访问器或自己调用它)时,它可能不会填充堆栈,因为调用可能是内联或其他内容,而程序只是永远递归。 –

+0

@JohnGardner:'LoweredUserName'是由Entity Framework生成的属性。它在其他地方没有造成任何问题该软件已经过测试并发布。这个问题发生在一台特定的客户端计算机上。我从来没有见过它发生在任何其他系统之前。我是积极的,问题不在那里,或者每个EF模型都会有问题,我永远也不会得到这个程序来发布。 –

3

总之未处理的异常

记住,至少有2个地方,你应该记录未处理的异常。 应用程序的AppDomain UnhandledException处理器的Application.DispatcherUnhandledExceptionEACH

如果你不抓住这些,应用程序将终止。

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

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

Exceptions in Managed Threads

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. 
} 

这样一点要注意,如果你最终在这些“全局”异常左撇子,你的应用程序处于未知状态,但是唯一有效的做法是记录问题并退出/重新启动应用程序;即使您仍然可以让应用程序运行,您现在也无法恢复。

+0

我不知道AppDomain.UnhandledException处理程序。我将不得不为下一个版本添加一个。这并没有帮助我找到现在正在杀死我的程序的问题。 –

+0

@ Pete-stensones如何将AppDomain UnhandledException处理程序添加到库类(即没有单个入口点的程序)?或者是不需要的? – Rikalous

+0

您通常会在您的主机程序的program.cs中添加应用程序域未处理的异常处理程序;因为通常您记录错误并让应用程序终止。 –

相关问题