首页  ·  知识 ·  编程语言
C#中unhandled异常处理的问题
网友    .NET  编辑:dezai   图片来源:网络
为了增强现在正在开发的系统的健壮性,需要捕获运行时出现的无法预料而且没有被处理(unhandled)的异常。

为了增强现在正在开发的系统的健壮性,需要捕获运行时出现的无法预料而且没有被处理(unhandled)的异常。查了资料后,找到了使用 Application.ThreadException 事件处理这些异常的方法,基本步骤包括,
1、为ThreadException事件添加一个处理异常的函数句柄
2、定义处理异常的函数
例子如下:
[STAThread]

static void Main()
{
  Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
  Application.Run(new FrmMain());
}

private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
  MessageBox.Show("Unhandled exception: "+e.Exception.ToString());
}
这种方法简单易行,而且处理效率较高,可以按照用户的意图,很方便的添加处理异常理的其他功能。但我发现,如果使用第三方提供的控件时,根本不起作用,原应可能是第三方控件运行在不同的线程中。在Microsoft的帮助中也确实提到了,上面的方法只能处理主线程中未处理的异常。好了,上网查,找到了下面的方法,使用 AppDomain.UnhandledException 替代Application.ThreadException。
首先需要了解的是,此时定义的事件处理函数需要在抛出异常的线程中执行,但是在主线程中给出异常提示都是在主线程中完成的,那么如何解决这个问题呢?下面的代码给出了一个比较完整的解决方案。

private delegate void ExceptionDelegate(Exception x);

static private FrmMain _MainForm;

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
  _MainForm = new FrmMain();
  AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AppDomain_UnhandledException);
  Application.Run(_MainForm);
}

private static void AppDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
  Exception exception;

  exception = e.ExceptionObject as Exception;
  if (exception == null)
{
// this is an unmanaged exception, you may want to handle it differently
    return;
}
  PublishOnMainThread(exception);
}

private static void PublishOnMainThread(Exception exception)
{
  if (_MainForm.InvokeRequired)
  {
    // Invoke executes a delegate on the thread that owns _MainForms's underlying window handle.
    _MainForm.Invoke(new ExceptionDelegate(HandleException), new object[] {exception});
  }
  else
  {
    HandleException(exception);
  }
}

private static void HandleException(Exception exception)
{
  if (SystemInformation.UserInteractive)
  {
    using (ThreadExceptionDialog dialog = new ThreadExceptionDialog(exception))
    {
      if (dialog.ShowDialog() == DialogResult.Cancel)
        return;
    }
    Application.Exit();
    Environment.Exit(0);
  }
}

private void ThreadMethod()
{
  throw new Exception("From new thread");
}

private void button1_Click(object sender, System.EventArgs e)
{
  Thread thread;
  thread = new Thread(new ThreadStart(ThreadMethod));
  thread.Start();
}
需要注意的是:
1、需要为所有的 AppDomain 的 UnhandledException 添加一个处理
2、 UnhandledExceptionEventArgs 参数中包含一个 IsTerminating 属性,表示是否中止 common language runtime

本文作者:网友 来源:网络
CIO之家 www.ciozj.com 微信公众号:imciow
   
免责声明:本站转载此文章旨在分享信息,不代表对其内容的完全认同。文章来源已尽可能注明,若涉及版权问题,请及时与我们联系,我们将积极配合处理。同时,我们无法对文章内容的真实性、准确性及完整性进行完全保证,对于因文章内容而产生的任何后果,本账号不承担法律责任。转载仅出于传播目的,读者应自行对内容进行核实与判断。请谨慎参考文章信息,一切责任由读者自行承担。
延伸阅读