• 利用委托机制处理.NET中的异常


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

    Terrylee20051210

    概述

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

    主线程的异常处理

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

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

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

     4        [STAThread]
     5        static void Main() 
     6        {    
     7            ///添加主线程的全局异常处理
     8            Application.ThreadException += new 
     9                ThreadExceptionEventHandler(
    10                MainUIThreadExceptionHandler);
    11
    12            Application.Run(new Form1());
    13        }

    处理程序:

     1public static void MainUIThreadExceptionHandler(Exception ex)
     2{
     3    MainUIThreadExceptionHandler(nullnew
     4        ThreadExceptionEventArgs(ex));
     5}

     6
     7/// <summary>
     8/// 主线程全局异常信息的处理
     9/// </summary>
    10/// <param name="sender"></param>
    11/// <param name="t"></param>

    12public static void MainUIThreadExceptionHandler(object
    13    sender, ThreadExceptionEventArgs e)
    14{
    15    MessageBox.Show(
    16        "应用程序发生了如下的异常信息"
    17        + "" + (char)13
    18        + (char)13 + e.Exception.Message
    19        + (char)13 + (char)13
    20        + "请于系统管理员取得联系!"
    21        + (char)13 + (char)13
    22        , "异常信息"
    23        , MessageBoxButtons.OK
    24        , MessageBoxIcon.Error
    25        , MessageBoxDefaultButton.Button1 
    26        , MessageBoxOptions.ServiceNotification);        
    27}


    工作线程的异常处理

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

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

     1/// <summary>
     2/// 在线程的入口点加入try-catch块
     3/// </summary>

     4private void DataSave()
     5{
     6    try
     7    {
     8        CreateException();
     9    }

    10    catch(Exception e)
    11    {
    12        ///通过delegate转向工作线程的异常处理
    13        new WorkerThreadExceptionHandlerDelegate(
    14            WorkerThreadExceptionHandler).BeginInvoke(e
    15            ,null
    16            ,null);
    17    }

    18}

    工作线程异常的处理:

     1/// <summary>
     2/// 声明工作线程的delegate
     3/// </summary>

     4public delegate void
     5    WorkerThreadExceptionHandlerDelegate(Exception e);
     6
     7/// <summary>
     8/// 工作线程的异常处理
     9/// </summary>
    10/// <param name="e"></param>

    11public void WorkerThreadExceptionHandler(Exception e)
    12{
    13    ///添加其他的处理代码
    14
    15    ///通知全局异常处理程序

    16    MainUIThreadExceptionHandler(
    17        thisnew System.Threading.
    18        ThreadExceptionEventArgs(e));
    19}

    总结

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

    完整的程序代码:

      1using System;
      2using System.Drawing;
      3using System.Collections;
      4using System.ComponentModel;
      5using System.Windows.Forms;
      6using System.Data;
      7using System.Threading;
      8
      9namespace UseDelegateException
     10{
     11    /// <summary>
     12    /// 功能:利用Delegate实现异常的全局处理
     13    /// 编写:Terrylee
     14    /// 日期:2005年12月10日
     15    /// </summary>

     16    public class Form1 : System.Windows.Forms.Form
     17    {
     18        private System.Windows.Forms.Button btnMainUIThread;
     19        private System.Windows.Forms.Button btnWorkThread;
     20        /// <summary>
     21        /// 必需的设计器变量。
     22        /// </summary>

     23        private System.ComponentModel.Container components = null;
     24
     25        public Form1()
     26        {
     27            //
     28            // Windows 窗体设计器支持所必需的
     29            //
     30            InitializeComponent();
     31
     32            //
     33            // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
     34            //
     35        }

     36
     37        /// <summary>
     38        /// 清理所有正在使用的资源。
     39        /// </summary>

     40        protected override void Dispose( bool disposing )
     41        {
     42            if( disposing )
     43            {
     44                if (components != null
     45                {
     46                    components.Dispose();
     47                }

     48            }

     49            base.Dispose( disposing );
     50        }

     51
     52        Windows 窗体设计器生成的代码
     94
     95        /// <summary>
     96        /// 应用程序的主入口点。
     97        /// </summary>

     98        [STAThread]
     99        static void Main() 
    100        {    
    101            ///添加主线程的全局异常处理
    102            Application.ThreadException += new 
    103                ThreadExceptionEventHandler(
    104                MainUIThreadExceptionHandler);
    105
    106            Application.Run(new Form1());
    107        }

    108        
    109        public static void MainUIThreadExceptionHandler(Exception ex)
    110        {
    111            MainUIThreadExceptionHandler(nullnew
    112                ThreadExceptionEventArgs(ex));
    113        }

    114
    115        /// <summary>
    116        /// 主线程全局异常信息的处理
    117        /// </summary>
    118        /// <param name="sender"></param>
    119        /// <param name="t"></param>

    120        public static void MainUIThreadExceptionHandler(object
    121            sender, ThreadExceptionEventArgs e)
    122        {
    123            MessageBox.Show(
    124                "应用程序发生了如下的异常信息"
    125                + "" + (char)13
    126                + (char)13 + e.Exception.Message
    127                + (char)13 + (char)13
    128                + "请于系统管理员取得联系!"
    129                + (char)13 + (char)13
    130                , "异常信息"
    131                , MessageBoxButtons.OK
    132                , MessageBoxIcon.Error
    133                , MessageBoxDefaultButton.Button1 
    134                , MessageBoxOptions.ServiceNotification);        
    135        }

    136        
    137        /// <summary>
    138        /// 声明工作线程的delegate
    139        /// </summary>

    140        public delegate void
    141            WorkerThreadExceptionHandlerDelegate(Exception e);
    142
    143        /// <summary>
    144        /// 工作线程的异常处理
    145        /// </summary>
    146        /// <param name="e"></param>

    147        public void WorkerThreadExceptionHandler(Exception e)
    148        {
    149            ///添加其他的处理代码
    150
    151            ///通知全局异常处理程序

    152            MainUIThreadExceptionHandler(
    153                thisnew System.Threading.
    154                ThreadExceptionEventArgs(e));
    155        }

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

    159        private void CreateException()
    160        {
    161            int a = 1;
    162            int b = 0;
    163
    164            int c;
    165            c = a/b;
    166        }

    167        
    168        /// <summary>
    169        /// 在线程的入口点加入try-catch块
    170        /// </summary>

    171        private void DataSave()
    172        {
    173            try
    174            {
    175                CreateException();
    176            }

    177            catch(Exception e)
    178            {
    179                ///通过delegate转向工作线程的异常处理
    180                new WorkerThreadExceptionHandlerDelegate(
    181                    WorkerThreadExceptionHandler).BeginInvoke(e
    182                    ,null
    183                    ,null);
    184            }

    185        }

    186
    187        /// <summary>
    188        /// 发生主线程异常
    189        /// </summary>
    190        /// <param name="sender"></param>
    191        /// <param name="e"></param>

    192        private void btnMainUIThread_Click(object sender, System.EventArgs e)
    193        {
    194            ///这里出现一个异常,我们不予捕获,交由全局处理函数
    195            CreateException();
    196        }

    197        
    198        /// <summary>
    199        /// 发生工作线程异常
    200        /// </summary>
    201        /// <param name="sender"></param>
    202        /// <param name="e"></param>

    203        private void btnWorkThread_Click(object sender, System.EventArgs e)
    204        {
    205            Thread t = new Thread( new ThreadStart(DataSave));
    206            t.Start();
    207        }

    208    }

    209}

    210
    支持TerryLee的创业产品Worktile
    Worktile,新一代简单好用、体验极致的团队协同、项目管理工具,让你和你的团队随时随地一起工作。完全免费,现在就去了解一下吧。
    https://worktile.com
  • 相关阅读:
    wp7订餐客户端源码
    AOP技术术语
    urlpattern详解
    .net 访问IBM DB2 数据库
    入驻博客园
    hadoop视频
    阿里OneData构建数据指标体系
    大数据领域全景解析
    PyTorch中梯度为什么默认自动累加,在反向传播前要手动将梯度清零?
    Pytorch:Dataloader和Dataset以及搭建数据部分的步骤
  • 原文地址:https://www.cnblogs.com/Terrylee/p/295243.html
Copyright © 2020-2023  润新知