zoukankan      html  css  js  c++  java
  • .Net下的全局异常捕获问题

            全局异常捕获主要目标并不是为了将异常处理掉防止程序崩溃。因为当错误被你的全局异常捕获器抓到的时候,已经证实了你程序中存在BUG。

      一般而言,我们的全局异常捕获主要作用就是接收到异常之后进行异常的反馈。

            大家都知道,异常是通过Throw命令抛出,一路从抛出的模块里上抛,如果中途没有被try...catch...抓住的话就会一直抛到CLR(公共语言运行时)。如果用栈来描述这个过程的话,那就是异常会从栈的栈顶一路下沉,直到中途被try...catch...抓住或者直至沉到栈底,被CLR接住。CLR接收到异常之后的处理方式非常的简单粗暴——直接报错,然后关闭程序。

            只要我们在程序把异常抛给CLR之前,抢先把异常捕获,那就可以做到全局异常处理了。不过这个try...catch...就必须放在栈的最下方。程序运行时栈的最下方函数其实就是程序运行时第一个调用的函数——main()函数。

    static void Main()
    {
        try
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new FrmMain());
        }
        catch (Exception ex)
        {
            MessageBox.Show(string.Format("捕获到未处理异常:{0}
    异常信息:{1}
    异常堆栈:{2}", ex.GetType(), ex.Message, ex.StackTrace));
        }
    }

    下面我们运用其他来处理全局异常。

    一、Application.ThreadException

    假设还是之前的那个程序,我们将程序的Program.cs内容填入以下代码:
    
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.ThreadException += Application_ThreadException;
             
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new FrmMain());
        }
     
        static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            Exception ex = e.Exception;
            MessageBox.Show(string.Format("捕获到未处理异常:{0}
    异常信息:{1}
    异常堆栈:{2}", ex.GetType(), ex.Message, ex.StackTrace));
        }
    }
     

    二、子线程异常捕获AppDomain.CurrentDomain.UnhandledException

        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.ThreadException += Application_ThreadException;
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
             
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new FrmMain());
        }
         
        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Exception ex = e.ExceptionObject as Exception;
            MessageBox.Show(string.Format("捕获到未处理异常:{0}
    异常信息:{1}
    异常堆栈:{2}
    CLR即将退出:{3}", ex.GetType(), ex.Message, ex.StackTrace, e.IsTerminating));
        }

    三、WPF的异常捕获

            public App()
            {
                this.Startup += new StartupEventHandler(App_Startup);
    
                this.DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);//UI线程的异常
                AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);//非UI线程的异常
                System.Threading.Tasks.TaskScheduler.UnobservedTaskException += App_UnobservedTaskException;//异步线程的异常
    
    
            }
    
            void App_Startup(object sender, StartupEventArgs e)
            {
                bool ret;
                mutex = new System.Threading.Mutex(true, "WpfMuerterrrterterttex", out ret);
                if (!ret)
                {
                    MessageBox.Show("课堂已经启动!");
                    Environment.Exit(0);
                }
            }
    
            void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
            {
                if (e.ExceptionObject is System.Exception)
                {
                   
                }
            }
    
            void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
            {
                e.Handled = true;
            }
    
            void App_UnobservedTaskException(object obj, System.Threading.Tasks.UnobservedTaskExceptionEventArgs e)
            {
    
            }
    
            int MyExceptionfilter(ref long a)
            {
                MessageBox.Show(a.ToString());
                return 0;
            }

    在此处理未处理的异常:

    /// <summary>
    /// App.xaml 的交互逻辑
    /// </summary>
    public partial class App : Application
    {
    protected override void OnStartup(StartupEventArgs e)
    {
    base.OnStartup(e);

    //注册Application_Error
    this.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);

    
    

    }

    
    

    //异常处理逻辑
    void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
    //处理完后,我们需要将Handler=true表示已此异常已处理过
    MessageBox.Show("程序执行时遇到未处理异常,即将关闭! 错误信息:"+e.Exception.Message);
    Environment.Exit(0);
    e.Handled = true;
    }
    }

     

    四、公共语言未能捕获的异常

    引入API

            public delegate int CallBack(ref long a);
            CallBack mycall;
    
            [System.Runtime.InteropServices.DllImport("kernel32")]
            private static extern Int32 SetUnhandledExceptionFilter(CallBack cb);
    
            [System.Runtime.InteropServices.DllImport("user32.dll")]
            public static extern int GetWindowText(IntPtr hWnd, ref string strBuffer, int nSize);

    WPF的App中

                mycall = new CallBack(MyExceptionfilter);
                SetUnhandledExceptionFilter(mycall);

    处理:

            int MyExceptionfilter(ref long a)
            {
                MessageBox.Show(a.ToString());
                return 0;
            }
  • 相关阅读:
    how to pass a Javabean to server In Model2 architecture.
    What is the Web Appliation Archive, abbreviation is "WAR"
    Understaning Javascript OO
    Genetic Fraud
    poj 3211 Washing Clothes
    poj 2385 Apple Catching
    Magic Star
    关于memset的用法几点
    c++ 函数
    zoj 2972 Hurdles of 110m
  • 原文地址:https://www.cnblogs.com/xietianjiao/p/7826844.html
Copyright © 2011-2022 走看看