2008-09-30 30 views
2

请注意,我意识到这已被解决here。这篇文章讨论了.NET 1.1中的异常处理,同时暗示了针对> .NET 2.0的更好的解决方案,所以这个问题特别针对更新的.NET版本。有没有办法在WinForms .NET 3.5应用程序中为未处理的异常定义动作?

我有一个Windows窗体应用程序,预计会频繁地意外丢失与数据库的连接,在这种情况下,它将重置为初始状态。

我已经通过我的自定义DBWrapper对象上的一组装饰器来进行错误日志记录,重试连接等。然而,在这之后,我想让错误落入堆栈。一旦它到达顶部并且未被处理,我希望它被吞下,并执行我的ApplicationResetter.Reset()方法。

谁能告诉我如何做到这一点?

如果这是不可能的,那么是否至少有一种方法可以解决这个问题,而不会引入ApplicationResetter对每个可能收到这样的错误的类的依赖,而且实际上并没有关闭并重新启动我的应用程序(这看起来很丑陋) ?

回答

0

对于Windows窗体线程(其中调用Application.Run()),在主要的开始分配ThreadException处理器() 。此外,我发现有必要调用SetUnhandledExceptionMode:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.Automatic); 
Application.ThreadException += ShowUnhandledException; 
Application.Run(...); 

这是一个示例处理程序。我知道这不是你要找的,但它显示处理程序的格式。请注意,如果您希望异常是致命的,则必须显式调用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(); 
     } 
    } 
} 
2

警告:不熟悉的3.5然而,有可能是一个更好的答案...

...但我的理解是,在活动时间内到达未处理的异常处理程序,该应用程序很可能将死 - 如果它不死,它可能是如此损坏,它应该无论如何死

如果你已经在处理一个db-not-there的情况下,并让其他异常通过,那么应用程序应该死因为它可能不稳定

+0

我处理由重试的情况和记录它,但是之后做我的DBWrapper.GetDataSet()仍然有或者返回的东西给客户或抛出一个错误。如果我抛出那么错误会冒泡,除非我抓住需要重置器依赖项的东西。我希望尽可能高。 – 2008-09-30 19:47:32

+0

如果在三个等待 - 重试周期后未能找到数据库,则返回null并让调用者检查该数据库。否则,抛出一个自定义的异常,并让应用程序死亡 - 没有应用程序可以弥补不稳定/无法访问的数据库。 – 2008-09-30 20:12:20

+0

但就是这一点,我可以返回null或我可以抛出一个错误,无论调用类必须采取ApplicationResetter依赖 – 2008-09-30 20:26:30

1

也许Application.ThreadException事件将满足您的需求:

static void Main() 
{ 
    Application.ThreadException += Application_ThreadException; 
    //... 
} 

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) 
{ 
    // call ApplicationResetter.Reset() here 
} 
1

还有System.Windows.Forms.Application.ThreadException事件和System.AppDomain.CurrentDomain.UnhandledException事件。

正如史蒂文提到的,这些将使您的应用程序处于未知状态。除了将调用引发到try/catch块中的异常之外,没有其他办法可以做到这一点。

0

在最新的MSDN问题未处理的异常的漂亮深入的解释: September 2008

相关问题