zoukankan      html  css  js  c++  java
  • 关于C_Sharp集中处理异常

    1.写在前面

    “异常意味着什么?”,想必不用对此做多余的解释,我们有理由相信在任何情况下任何应用程序都有可能出现异常,若在程序中没有对异常进行处理,则操作系统会以粗暴的方式处理掉它(弹出错误提示框),在很多应用软件中都可以看到这样的提示框,无疑会影响用户的体验。所以,我们完全有必要对应用程序进行全方位的异常处理,尽可能地覆盖所有可能出现的异常,而程序的异常处理本身是一个非常重要却极易被忽视的问题。

    2.一般的异常处理方式

    无非就是try...catch...finally...的应用,把所有自认为可能出现异常的代码都用try块wrap起来,没错,这确实是一种完全可行的方法,但却不是最合适的做法。原因如下:

    假如需要开发一个WinForm应用程序,首先生成项目时VS自动生成机器代码,然后编码人员进行编码,实现需要的功能,编码人员非常谨慎,所以他在自己编写的代码中添加了若干个异常处理块。。。无论怎么测试都没有出现未被捕获的异常,他很开心,可是有一天运行应用程序时还是发生了异常,这是为什么?答案是编码人员没错,VS生成的机器代码也没错,而是操作系统出错了,在加载该APP时可能遇到了Interruption,进而引发了异常(当然,只是举个例子)

    我们可以看到,若撇开系统异常以及RunTimeException不讲,编码人员做得非常好,这样的做法是值得我们学习的,也必须养成这样的习惯。

    3.对于一般异常处理的建议

    在上面介绍的一般的异常处理方式中,我们不得不需要关注代码臃肿的问题,try...catch...finally...无疑会占用很大篇幅,这个是可以避免的,可以把异常尽量集中处理,推荐的做法是对下层的Exception直接throw出去(在函数定义时添上throws声明即可),在Main函数中统一处理(因为到这里就不能继续throw了,否则。。。)

    其次在catch块处理异常时,我们可以新建一个独立的ExceptionClass定义各种异常的处理方法,避免出现大量冗余代码

    每个线程都要对应一个异常处理方法,Main属于主线程,在自定义的子线程里应该使用独立的异常处理

    4.集中式异常处理

    上面的第一条建议只适合控制台应用程序,不存在复杂的人机交互,对于WinForm应用程序将不再适用,那么在WinForm应用程序中怎样合理地处理异常?

    C Sharp的Application.ThreadException为我们提供了便利,用于处理UI线程异常,AppDomain.CurrentDomain.UnhandledException用于处理非UI线程异常

    用法如下:

     1 static class Program
     2     {
     3         /// <summary>
     4         /// 应用程序的主入口点。
     5         /// </summary>
     6         [STAThread]
     7         [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
     8         static void Main()
     9         {
    10             Application.EnableVisualStyles();
    11             Application.SetCompatibleTextRenderingDefault(false);
    12             //处理未捕获的异常,始终将异常传送到 ThreadException 处理程序
    13             Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    14             //集中处理异常
    15             //订阅ThreadException事件,处理UI线程异常,处理方法为handler1
    16             Application.ThreadException += new ThreadExceptionEventHandler(handler1);
    17             //订阅UnhandledException事件,处理非UI线程异常,处理方法为handler2
    18             AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(handler2);
    19 
    20             Application.Run(new MainForm());
    21         }
    22 
    23         public static void handler1(object sender, ThreadExceptionEventArgs e)
    24         {
    25             MessageBox.Show("哎呀,好像出错了T_T");
    26             Application.Exit();
    27         }
    28 
    29         public static void handler2(object sender, UnhandledExceptionEventArgs e)
    30         {
    31             MessageBox.Show("哎呀,好像出错了T_T");
    32             Application.Exit();
    33         }
    34     }

    特别说明:

    1>请注意Main方法里各个语句的顺序,集中异常处理的相关代码必须放在Application.Run();语句之前,否则没有效果

    2>以上代码都在program.cs中,因为程序入口Main在这里

    3>若对这样的处理方式还存在疑问,可以查看官方文档以及例程序源码http://msdn.microsoft.com/zh-cn/library/system.windows.forms.application.setunhandledexceptionmode.aspx

    5.最后的建议(请务必看看)

    1>集中式异常处理并不是万能的,不建议过分依赖这样的处理方式

    2>集中式异常处理只是最后的一道防线,程序内部仍然应该添加尽可能完善的异常处理

    3>任何异常处理都应该包括两个部分,即A.记录异常信息(写入ErrorLog或者发送到作者邮箱等等)B.善后操作(退出APP或者其它补救处理)

  • 相关阅读:
    php多态
    ssl certificate problem: self signed certificate in certificate chain
    test plugin
    open specific port on ubuntu
    junit vs testng
    jersey rest service
    toast master
    use curl to test java webservice
    update folder access
    elk
  • 原文地址:https://www.cnblogs.com/ayqy/p/3583826.html
Copyright © 2011-2022 走看看