利用委托机制处理.NET中的异常(引用)

From http://www.cnblogs.com/Terrylee/archive/2005/12/12/295243.html
(创新的前提是模仿,所以引用别人的文章是自身创新提高的前提,关键是自己需要真正的消化理解)

概述

.NET中,可以轻松的通过try-catch块来捕获异常。为了防止在应用程序中出现未处理的异常,可以通过添加一个全局的异常处理函数,如果是多线程的处理,还必须考虑除了主线程之外的工作线程中的异常处理办法,这里用委托机制来实现。


主线程的异常处理

使用Application对象中的ThreadException属性设置一个delegate来捕获所有的未处理的主线程中出现的异常。注意这个全局异常处理程序,只能捕获到主线程中的异常,对于我们自己添加的工作线程、辅助线程的异常是捕获不到的。

在应用程序入口添加全局异常处理:


  static void Main()
        
{

            Application.ThreadException 
+= new ThreadExceptionEventHandler(Form1.MainUIThreadExceptionHandler);

            
//Application.EnableVisualStyles();
            
//Application.SetCompatibleTextRenderingDefault(false);
            
//Application.Run(new Form1());
            System.Windows.Forms.Application.Run(new Form1());
        }


处理程序:

  public static void MainUIThreadExceptionHandler(Exception ex)
        
{
            MainUIThreadExceptionHandler(
nullnew ThreadExceptionEventArgs(ex));
        }

  
public static void MainUIThreadExceptionHandler(object sender, ThreadExceptionEventArgs e)
        
{
            MessageBox.Show(
            
"应用程序发生了如下的异常信息"
            
+ "" + (char)13
            
+ (char)13 + e.Exception.Message
            
+ (char)13 + (char)13
            
+ "请于系统管理员取得联系!"
            
+ (char)13 + (char)13
            , 
"异常信息"
            , MessageBoxButtons.OK
            , MessageBoxIcon.Error
            , MessageBoxDefaultButton.Button1
            , MessageBoxOptions.ServiceNotification);
        }

工作线程的异常处理

编写多线程代码时,我们必须考虑在工作线程中出现的异常。在线程的入口使用try-catch块,并通过delegate将发生的异常通知给主线程。必须将异常信息通知主线程,否则应用程序不会报错,异常将会消失。

在线程入口使用try-catch块:

  private void DataSave()
        
{
            
try
            
{
                CreateException();
            }

            
catch (Exception e)
            
{
                
/**/
                
///通过delegate转向工作线程的异常处理
                new WorkerThreadExceptionHandlerDelegate(WorkerThreadExceptionHandler).BeginInvoke(e, nullnull);
            }

        }


工作线程异常的处理:

public delegate void WorkerThreadExceptionHandlerDelegate(Exception e);
    
public void WorkerThreadExceptionHandler(Exception e)
        
{
            
/**/
            
///添加其他的处理代码

            
///通知全局异常处理程序

            MainUIThreadExceptionHandler(
                
thisnew System.Threading.
                ThreadExceptionEventArgs(e));
        }


总结

对于捕获到异常,我们可以Log到文件或者数据库,但是必须保证捕获到所有的异常,以上通过委托机制实现了.NET中的主线程以及工作线程中的异常捕获。

 

完整的程序代码:

主文件:
using System;
using System.Collections.Generic;
using System.Windows.Forms;

using System.Threading;

namespace WindowsApplication2
{
    
static class Program
    
{


       

        
/// <summary>
        
/// 应用程序的主入口点。
        
/// </summary>

        [STAThread]
        
static void Main()
        
{

            Application.ThreadException 
+= new ThreadExceptionEventHandler(Form1.MainUIThreadExceptionHandler);

            
//Application.EnableVisualStyles();
            
//Application.SetCompatibleTextRenderingDefault(false);
            
//Application.Run(new Form1());
            System.Windows.Forms.Application.Run(new Form1());
        }


       

    }

}

Form1.cs文件:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
///线程的异常处理
namespace WindowsApplication2
{
    
public partial class Form1 : Form
    
{
        
public delegate void WorkerThreadExceptionHandlerDelegate(Exception e);
        
public Form1()
        
{
            InitializeComponent();
        }

        
public static void MainUIThreadExceptionHandler(Exception ex)
        
{
            MainUIThreadExceptionHandler(
nullnew ThreadExceptionEventArgs(ex));
        }

        
public static void MainUIThreadExceptionHandler(object sender, ThreadExceptionEventArgs e)
        
{
            MessageBox.Show(
            
"应用程序发生了如下的异常信息"
            
+ "" + (char)13
            
+ (char)13 + e.Exception.Message
            
+ (char)13 + (char)13
            
+ "请于系统管理员取得联系!"
            
+ (char)13 + (char)13
            , 
"异常信息"
            , MessageBoxButtons.OK
            , MessageBoxIcon.Error
            , MessageBoxDefaultButton.Button1
            , MessageBoxOptions.ServiceNotification);
        }

        
/**/
        
/// <summary>
        
/// 制造异常信息,这里抛出一个除0的异常
        
/// </summary>

        private void CreateException()
        
{
            
int a = 1;
            
int b = 0;
            
int c;
            c 
= a / b;
        }

        
private void DataSave()
        
{
            
try
            
{
                CreateException();
            }

            
catch (Exception e)
            
{
                
/**/
                
///通过delegate转向工作线程的异常处理
                new WorkerThreadExceptionHandlerDelegate(WorkerThreadExceptionHandler).BeginInvoke(e, nullnull);
            }

        }

        
public void WorkerThreadExceptionHandler(Exception e)
        
{
            
/**/
            
///添加其他的处理代码

            
///通知全局异常处理程序

            MainUIThreadExceptionHandler(
                
thisnew System.Threading.
                ThreadExceptionEventArgs(e));
        }

        
private void btnMainUIThread_Click(object sender, EventArgs e)
        
{
            CreateException();
        }

        
private void btnWorkThread_Click(object sender, EventArgs e)
        
{
            Thread t 
= new Thread(new ThreadStart(DataSave));
            t.Start();
        }

    }

}
posted @ 2007-03-20 18:12  jhtchina  阅读(596)  评论(0编辑  收藏  举报