zoukankan      html  css  js  c++  java
  • 各类异常捕获

    一、UI线程异常:

    1)直接在主线程中的异常,直接用try……catch捕获(如果你怀疑某个代码会抛出异常)。

    2)其它可能性:建议使用Application.ThreadException+Application.SetUnhandledException捕获异常,并防止应用程序终止。

    1  private void button1_Click(object sender, EventArgs e)
    2         {
    3             throw new Exception("UI异常抛出");
    4         }

    在Program.cs入口函数中:

    public class Program
        {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.ThreadException += Application_ThreadException;
                Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Form1 f1 = new Form1();
                Application.Run(f1);
            }
    
            private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
            {
                using (var f = File.AppendText("c:\error2.txt"))
                {
                    f.WriteLine(e.Exception.Message);
                }
            }
        }

    点击按钮,会抛出异常(UI异常)。被写入日志,程序可以继续运行。

    二、Task异常捕获:

    1)使用Wait捕获(因为Wait会把Task异常放入到主线程,所以主线程可以捕获)。

    注意,使用Wait捕获的异常不是Exception而是AggregateException,其中可以获得InnerExceptions,使用foreach的Exception遍历:

     try
                {
                    Task.Factory.StartNew(() =>
                       {
                           throw new Exception("人工创建的线程异常");
                       }).Wait();
    
                }
                catch (AggregateException ex)
                {
                    foreach (var item in ex.Flatten().InnerExceptions)
                    {
                        //在这里处理你的异常
                    }
                }

    2)在Task内部处理(推荐)

     Task.Factory.StartNew(() =>
                       {
                          try
                            {
                            }
                          catch (Exception e)
                             {
                             }
                       }).Wait();

    3)使用Continue方法处理:

     Task.Factory.StartNew(() =>
                {
                    throw new Exception("人工创建的线程异常");
                }).ContinueWith(t => t.Exception.Flatten()……);

    4)当使用await(异步的时候),直接在GUI线程try……catch……捕获异常(像普通代码一样,什么异常就catch什么异常)。

    5)所有Task的异常(没有使用await或者Wait,纯多线程异常,内部也没有处理过)会在Task被Finailize之后被主线程捕获,抛出异常并终止主程序。此时应该在WinForm(Console控制台在Main入口函数中),使用TaskSchedule.UnobservedTaskException:

    namespace CSharpWinForm
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
    
                TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
            }
    
    
            private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
            {
                using (var f = File.AppendText("c:\error.txt"))
                {
                    foreach (var item in e.Exception.Flatten().InnerExceptions)
                    {
                        f.WriteLine("Task异常:"+item.Message);
                    }
                }
                e.SetObserved();
            }
    
    
            private void button1_Click(object sender, EventArgs e)
            {
                Task.Factory.StartNew(() =>
                {
                    throw new Exception("人工创建的线程异常");
                });
                Thread.Sleep(500);
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
        }
    }

    3)Thread和ThreadPool的异常:

    此异常会导致主程序崩溃,必须使用内部try……catch捕获。当然,我们可以使用AppDomain.CurrentDomain的UnhandledException捕获(但是无法取消异常,仍然会有此异常):

    public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                Thread th = new Thread(() => 
                {
                    throw new Exception("异常");
                });
                th.Start();
            }
        }
     public class Program
        {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Form1 f1 = new Form1();
                Application.Run(f1);
            }
    
    
            private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
            {
                using (var f = File.AppendText("c:\error2.txt"))
                {
                    f.WriteLine(e.ExceptionObject.ToString());
                }
            }
        }
  • 相关阅读:
    Privilege(特权)
    Access Control Model(访问控制模型)
    nrm 常用命令
    nrm安装完成运行报错 环境变量配置问题
    nrm : 无法加载文件 C:Program Files odejs rm.ps1,因为在此系统上禁止运行脚本。
    ts 实现简单的video播放器 源码: https://github.com/yuhualiang/miProjectTwo
    ts 弹窗组件
    替换字符串中图片的src
    03-05 变量声明
    03-04 变量声明
  • 原文地址:https://www.cnblogs.com/ServiceboyNew/p/5873511.html
Copyright © 2011-2022 走看看