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或者其它补救处理)

  • 相关阅读:
    iOS--------cocoapods遇到的问题
    NTFS
    交换机配置telnet
    交换机
    华为模拟器配置telnet
    路由器
    OSI模型
    网络拓扑
    为什么CAS加锁是线程安全的?--理解原子操作
    零基础自学编程选哪种语言好?世上最好编程语言推荐
  • 原文地址:https://www.cnblogs.com/ayqy/p/3583826.html
Copyright © 2011-2022 走看看