• C#中的异常处理


    在Program.cs中添加如下代码,之后整个应用程序都不需要额外处理异常了。所以的异常都会在这里处理

    补充:

            还需要考虑没有文件的写权限,catch (UnauthorizedAccessException ex)

           Access to the path 'D:ChuckLuGitEdenredLISA_5.0.0.0LISA.ControlPanelLISA.ControlPanelinDebuglog20171206.0.log' is denied.

            还需要考虑文件被其他进程占用 ,catch (IOException ex)

           The process cannot access the file 'D:ChuckLuGitEdenredLISA_5.0.0.0LISA.ControlPanelLISA.ControlPanelinDebuglog20171206.0.log' because it is being used by another process.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    using WinClient.UI;
    using ZBM.ZITaker.Log;
    using ZBM.Utility;
    
    namespace WinClient
    {
        static class Program
        {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                try
                {
                    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
                    Application.ThreadException += Application_ThreadException;//处理UI线程的异常
    
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new FormMain());
                }
                catch (Exception ex)
                {
                    DealException(ex);
                }
            }
    
            /// <summary>
            /// 处理UI线程的异常
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
            {
                DealException(e.Exception);
            }
    
            static void DealException(Exception ex)
            {
                if (ex != null)
                {
                    ExceptionLog.Instance.WriteLog(ex, LogType.UI);
                    ZBMMessageBox.ShowError(ex);
                }
            }
        }
    }

    解释:
    Application.ThreadException处理的是UI线程的异常

    需要注意的是  还有另外一个处理异常的事件(然并卵)

    AppDomain.CurrentDomain.UnhandledException处理的是非UI线程的异常(如:子线程的异常)

    需要注意的是AppDomain.CurrentDomain.UnhandledException虽然能够捕获子线程的异常,但是子线程那边还是会崩溃的。从未导致整个应用程序结束。

    这就要求,子线程需要自行捕获异常,然后将异常抛出到UI线程

    this.BeginInvoke((Action)delegate
    {
    throw ex;
    });

    通过以下方式,将非UI线程的线程抛出到UI线程来处理。

    private void CreateThread()
            {
                Thread thread = new Thread(Temp);
                thread.IsBackground = true;
                thread.Start();
            }
    
            private void Temp()
            {
                try
                {
                    int a = 3;
                    int b = 0;
                    int c = a / b;
                }
                catch (Exception ex)
                {
                    this.BeginInvoke((Action)delegate
                    {
                        throw ex;
                    });
                }
              
            }

    以上处理方法的不足之处在于,所以的异常都会以MessageBox的方式显示给用户

    但是,如果有的线程是需要一直在后台运行的,那么多捕获到异常后。显示MessageBox的时候,貌似会把UI卡死。

    ===============2015年09月07日更新====================

    子线程的线程还是需要通过事件通知的方式来处理,因为并不是所有的类都有BeginInvoke的方法

    class ChildThreadExceptionOccuredEventArgs : EventArgs
    {
    internal Exception Exception;
    }

    class EventNotifyManager
        {
    
            private EventNotifyManager() { }
            private static readonly EventNotifyManager instance = new EventNotifyManager();
    
            public static EventNotifyManager Instance
            {
                get { return instance; }
            }
    
            /// <summary>
            /// 子线程出现异常 子线程的异常无法抛出到主线程,所以需要使用事件通知机制
            /// </summary>
            public event EventHandler<ChildThreadExceptionOccuredEventArgs> ChildThreadExceptionOccured;
            public void OnChildThreadExceptionOccured(ChildThreadExceptionOccuredEventArgs e)
            {
                EventHandler<ChildThreadExceptionOccuredEventArgs> handler = ChildThreadExceptionOccured;
                if (handler != null)
                {
                    handler(this, e);
                }
            }
    
        }

    可以在Main函数中,增加注册此事件,然后在启用子线程的时候,在子线程的处理方法中,try catch,捕获到异常之后,就用这个事件把异常抛出到主线程中

  • 相关阅读:
    mysql导sql脚本
    oracle导sql脚本
    基于jdk proxy的动态代理模式
    vue组件之组件的生命周期
    vue组件之组件间的通信
    python-爬虫scrapy框架安装及基本使用
    mongdb的使用
    python-爬虫 多线程爬虫
    python-爬虫 爬虫利器BeautifulSoup
    python-爬虫lxml库
  • 原文地址:https://www.cnblogs.com/chucklu/p/4704775.html
Copyright © 2020-2023  润新知