有没有办法在WinForms .NET 3.5应用程序中为未处理的exception定义操作?
请注意,我意识到这已在此处解决。 那篇文章讨论了.NET 1.1中的exception处理,同时暗示有一个更好的解决方案> .NET 2.0所以这个问题具体是关于更新的.NET版本。
我有一个Windows窗体应用程序,预计会频繁和意外地失去与数据库的连接,在这种情况下,它将自身重置为其初始状态。
我已经通过我的自定义DBWrapper对象上的一组装饰器进行错误记录,重试连接等。 然而,在那之后,我想让错误通过堆栈。 一旦它到达顶部并且未处理,我希望它被吞下并且我的ApplicationResetter.Reset()方法被执行。
谁能告诉我怎么做?
如果这是不可能的,那么至少有一种方法可以处理这个问题,而不会将ApplicationResetter依赖于每个可能收到此类错误并且实际上没有关闭并重新启动我的应用程序的类(这看起来很丑陋)?
对于Windows窗体线程(调用Application.Run()),在Main()的开头分配一个ThreadException处理程序。 另外,我发现有必要调用SetUnhandledExceptionMode:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.Automatic); Application.ThreadException += ShowUnhandledException; Application.Run(...);
这是一个示例处理程序。 我知道这不是你想要的,但它显示了处理程序的格式。 请注意,如果您希望exception是致命的,则必须显式调用Application.Exit()。
static void ShowUnhandledException(object sender, ThreadExceptionEventArgs t) { Exception ex = t.Exception; try { // Build a message to show to the user bool first = true; string msg = string.Empty; for (int i = 0; i < 3 && ex != null; i++) { msg += string.Format("{0} {1}:\n\n{2}\n\n{3}", first ? "Unhandled " : "Inner exception ", ex.GetType().Name, ex.Message, i < 2 ? ex.StackTrace : ""); ex = ex.InnerException; first = false; } msg += "\n\nAttempt to continue? (click No to exit now)"; // Show the message if (MessageBox.Show(msg, "Unhandled exception", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.No) Application.Exit(); } catch (Exception e2) { try { MessageBox.Show(e2.Message, "Fatal error", MessageBoxButtons.OK, MessageBoxIcon.Stop); } finally { Application.Exit(); } } }
警告:不熟悉3.5,可能有更好的答案……
…但我的理解是,当事件到达未处理的exception处理程序时,应用程序可能会死亡 – 如果它没有死亡,它可能会被破坏,无论如何都应该死
如果你已经在处理db-not-there的情况并且让其他exception通过,那么应用程序应该死掉,因为它可能不稳定
也许Application.ThreadException事件可以满足您的需求:
static void Main() { Application.ThreadException += Application_ThreadException; //... } static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) { // call ApplicationResetter.Reset() here }
有System.Windows.Forms.Application.ThreadException
事件和System.AppDomain.CurrentDomain.UnhandledException
事件。
如史蒂文所述,这些将使您的应用程序处于未知状态。 除了将可能引发exception的调用放在try / catch块中之外,没有其他方法可以做到这一点。
在最新的MSDN问题中对未处理的exception进行了非常深入的解释: 2008年9月