2011-10-03 134 views
2

我们有一个服务器实例的应用程序,很少,但我们有内存不足的例外(程序没有泄漏,只是实例很小,它运行的数据量相当大) 。如何避免错误消息窗口

这将不是问题,因为我们监视该服务器实例上的进程,并且如果在进程列表中找不到某些进程,则会发送警报电子邮件。

现在的问题是这个:

enter image description here

阻止进程从进程列表中消失,所以我们没有得到警报电子邮件关于它的失败。是否有可能禁用此消息,如果程序失败了,我们没有捕捉到,它会在没有用户交互的情况下关闭?

回答

1

假设Windows窗体,我通常做多的步骤,以防止此消息框。

首先,我连接多个处理程序在Main功能:当否则出现未处理的异常

[STAThread] 
private static void Main() 
{ 
    Application.ThreadException += 
     application_ThreadException; 

    Application.SetUnhandledExceptionMode(
     UnhandledExceptionMode.CatchException); 

    AppDomain.CurrentDomain.UnhandledException += 
     currentDomain_UnhandledException; 

    Application.Run(new MainForm()); 
} 

那些处理程序被调用。我将它们定义是这样的:

private static void application_ThreadException(
    object sender, 
    ThreadExceptionEventArgs e) 
{ 
    doHandleException(e.Exception); 
} 

private static void currentDomain_UnhandledException(
    object sender, 
    UnhandledExceptionEventArgs e) 
{ 
    doHandleException(e.ExceptionObject as Exception); 
} 

实际doHandleException功能,然后将其称为不实际的错误处理。通常这会记录错误并通知用户,让他有选择继续应用程序或退出它。

从现实世界的应用程序示例如下:

private static void doHandleException(
    Exception e) 
{ 
    try 
    { 
     Log.Instance.ErrorException(@"Exception.", e); 
    } 
    catch (Exception x) 
    { 
     Trace.WriteLine(string.Format(
       @"Error during exception logging: '{0}'.", x.Message)); 
    } 

    var form = Form.ActiveForm; 
    if (form == null) 
    { 
     MessageBox.Show(buildMessage(e), 
       "MyApp", MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 
    else 
    { 
     MessageBox.Show(form, buildMessage(e), 
       "MyApp", MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 
} 

随着辅助函数:

public static string buildMessage(Exception exception) 
{ 
    var result = new StringBuilder(); 

    while (exception != null) 
    { 
     result.AppendLine(exception.Message); 
     result.AppendLine(); 
     exception = exception.InnerException; 
    } 

    return result.ToString().Trim(); 
} 

如果您使用的不是Windows窗体,但如一个控制台应用程序或WPF,一些处理程序不存在,而另一些则存在。

想法保持不变:订阅正在被调用的事件处理程序,如果您的代码块周围没有try...catch

就我个人而言,我尝试尽可能少的那些try...catch块(理想情况下没有)。

2

不知道你是否可以停用这个 - 但我认为你不应该这样做。 在您的应用程序中查找错误/问题,并通过严重关机或在第一种情况下防止出现问题来处理问题。 其他一切都将是一个真正的原始解决方法,我不认为你的客户会很高兴有这样的行为(毕竟不会有数据丢失?如果不是这样,总是有错误/未完成触摸)

1

您可以在您的程序中放置一个全局try/catch块并退出程序以防意外的异常。

1

如果使用WPF,您可以尝试在您的app.xaml.cs中发现以下两个例外。可能还有其他的/互补的例外处理,但是这是两个我通常寻找:

AppDomain.CurrentDomain.UnhandledException - “此事件提供捕获的异常的通知它允许应用程序记录有关前的异常信息。系统默认处理程序向用户报告异常并终止应用程序如果有足够的关于应用程序状态的信息可用,则可以采取其他措施 - 例如保存程序数据以备以后恢复。如果不处理异常,则会损坏。“

Dispatcher.UnhandledException - “在通过Invoke或BeginInvoke执行委托期间抛出并未捕获到线程异常时发生。”

即:

public partial class App : Application 
{ 
public App() 
{ 
    this.Dispatcher.UnhandledException += DispatcherUnhandledException; 
    AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException; 
} 

private void CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) 
{ 
    // log and close gracefully 
} 


private new void DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) 
{ 
    e.Handled = true; 
    // log and close gracefully 
} 
}