C#中处理多线程Task中的异常

当我们使用Task.Run(()=>{})开启一个线程,如果线程里面有错误,外面需要处理捕获异常,很自然的方法我们在外部加try{ } Catch(Exception e){ } ,但是这种方法在外部捕获不了异常,如下:

            try
            {
                var task = Task.Run(() =>
                {
                        int a = 10;
                        int b = 0;
                        int c = a / b;
                });
            }
            catch
            {
                MessageBox.Show("出现异常");
            }

上面不会出现弹窗出现异常的信息,因为异常信息没有被抛到外面来,针对多线程Task的异常处理找到了几种处理方法。

1.使用全局多线程异常处理

 TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
 private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
 {
       MessageBox.Show(e.Exception.InnerException.Message);
       e.SetObserved();
 }

这里捕获的e.ExceptionAggregateException类型的,如果直接获取其Message,会出现未通过等待任务或访问任务的 Exception 属性观察到任务的异常。因此,终结器线程重新引发了未观察到的异常,根本就没法知道线程里面出现了什么异常,正确的方法是使用e.Exception.InnerException.Message,可以知道线程里面具体出现了什么异常.

2.Task.ContinueWith处理

 //2.使用ContinueWith(t=>{},TaskContinuationOptions.OnlyOnFaulted)进行异常后的处理
 var task2 = Task.Run(() =>
 {
     throw new ArgumentNullException("参数为Null");
 });
 task2.ContinueWith(t => { MessageBox.Show(t.Exception.InnerException?.Message); }, TaskContinuationOptions.OnlyOnFaulted);//这个会进行错误处理

3.直接try…catch捕获task.Wait();

 //4.Try{ task.Wait(); }Catch(Exception ex){};
 CancellationToken ct = new CancellationToken();
 var task3 = Task.Run(() => { throw new InvalidOperationException("无效操作"); }, ct);
 try
 {
     task3.Wait(ct);
 }
 catch (AggregateException ex)
 {
     MessageBox.Show(ex.InnerException.Message);
 }

上面就是常见的几种处理方法.

参考:What is the best way to catch exception in Task?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值