Async下处理多个异常
Task Parallel Library (TPL) 中,当你使用async/await 语法关键字时,你可能遇到以下异常处理的情况: Catch 块只会处理第一个异常而忽略其它的异常。来看下面代码块:
1: private static async void TestCatchExceptionWithTPL()
2: {
3: try
4: {
5: await Task.Factory.StartNew(() =>
6: {
7: Task.Factory.StartNew(() =>
8: { throw new NullReferenceException(); },
9: TaskCreationOptions.AttachedToParent);
10: Task.Factory.StartNew(() =>
11: { throw new ArgumentException(); },
12: TaskCreationOptions.AttachedToParent);
13: });
14: }
15: catch (AggregateException aex)
16: {
17: // this catch will never be target
18: }
19: catch (Exception ex)
20: {
21: Console.WriteLine("## {0} ##", ex.GetType().Name);
22: }
23: }
执行上面的代码,有注意8,11行分别有两个Exception,而这时到第一个Catch块中AggregateException只会捕捉第一个NullReferenceException异常,这是By Design的问题。有个解决方案是这样的:
1: try
2: {
3: Task t = Task.Factory.StartNew(() =>
4: {
5: Task.Factory.StartNew(() =>
6: { throw new NullReferenceException(); },
7: TaskCreationOptions.AttachedToParent);
8: Task.Factory.StartNew(() =>
9: { throw new ArgumentException(); },
10: TaskCreationOptions.AttachedToParent);
11: });
12: await t.ContinueWith(tsk => { if (tsk.Exception != null) throw tsk.Exception; });
13: }
14: catch (AggregateException ex)
15: {
16: foreach (var exc in ex.Flatten().InnerExceptions)
17: {
18: Console.WriteLine(exc.GetType().Name);
19: }
20: }
注意上面12行代码,使用了CoutinueWith方法,为了让代码更加简洁了,我们可以写一个扩展方法:
/// <summary>
/// ThrowMultiple
/// </summary>
/// <param name="t">Task</param>
/// <returns>Task type</returns>
public static Task ThrowMultiple(this Task t)
{
return t.ContinueWith(tsk => { if (tsk.Exception != null) throw tsk.Exception; });
}
/// <summary>
/// ThrowMultiple
/// </summary>
/// <typeparam name="T">Task this</typeparam>
/// <param name="t">Task t</param>
/// <returns>Task generic</returns>
public static Task<T> ThrowMultiple<T>(this Task<T> t)
{
return t.ContinueWith(tsk =>
{
if (tsk.Exception != null)
throw tsk.Exception;
return tsk.Result;
});
}
然后代码就是变成这样了:
1: try
2: {
3: await Task.Factory.StartNew(() =>
4: {
5: Task.Factory.StartNew(() =>
6: { throw new NullReferenceException(); },
7: TaskCreationOptions.AttachedToParent);
8: Task.Factory.StartNew(() =>
9: { throw new ArgumentException(); },
10: TaskCreationOptions.AttachedToParent);
11: }).ThrowMultiple();
12: }
13: catch (AggregateException aex)
14: {
15: // this catch will never be target
16: }
17: catch (Exception ex)
18: {
19: Console.WriteLine("## {0} ##", ex.GetType().Name);
20: }
有看到上面代码11行的变化为我们扩展方法。就这么简单,以上代码在Vs2012下 .net framework 4.5 version 下测试通过,希望对你开发有帮助。
您可能感兴趣的文章:
Asp.net MVC 4 异步方法
作者:Petter Liu
出处:http://www.cnblogs.com/wintersun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
该文章也同时发布在我的独立博客中-Petter Liu Blog。
Async下处理多个异常相关推荐
- (笔记)Linux Root下的.gvfs出现异常解决办法
(笔记)Linux Root下的.gvfs出现异常解决办法 参考文章: (1)(笔记)Linux Root下的.gvfs出现异常解决办法 (2)https://www.cnblogs.com/tdyi ...
- Linux中的报错命令,Linux学习教程-Linux下命令的一些异常情况
导读 命令不全:在命令没有输入完 (引号或括号没有配对),就不小心按下了Enter键,终端会提示出一个>代表命令不完整,这是可以继续输入,也可以ctrl+c终止输入,重新再来.(下面sed命令使 ...
- win10下桌面图标显示异常
如何win10下桌面图标显示异常 原因: 图标缓存损坏 解决方案 删除损坏图标 重新创建 重启电脑 如果还是加载不出 原因:损坏图标缓存已安装进win10 进入window instllar 在重新删 ...
- Win7下PDF图标显示异常排除
Win7下PDF图标显示异常排除 文件图标显示异常的原因及检查排除步骤 文件关联异常 图标缓存异常 图标文件损坏 文件图标显示异常的原因及检查排除步骤 文件关联异常 Control Panel\All ...
- C#下没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))
C#下没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG)) 参考文章: (1)C#下没有注册类 (异常来自 HRESULT:0x80040154 ...
- linux下怎么查看程序异常,linux程序莫名异常怎么查
内存异常经常导致程序出现莫名其妙的错误,往往很难查证,本文介绍在linux下的各种常见内存异常的查证工具和方法. 1 访问空指针/未初始化指针/重复释放内存 对于像访问空指针.未初始化指针(非法地址) ...
- oracle11g exp 00028,解决Linux系统下exp导入EXP-00028异常
问题描述: 在Linux系统中,对某个数据库用户进行exp导出备份时,出现下述异常: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 ...
- Linux下使用Vim编辑器异常退出E325:ATTENTION错误
Linux下使用vim编辑文件时,因为闪退或者卡住异常关闭终端导致出现E325:ATTENTION错误如下所示: 在当前目录下使用ls命令查看,此时并没有.main.cpp.swp文件 必须使用ls ...
- window40系统怎么重装不下服务器,Win10系统异常不想重装怎么办 四种系统修复方法哪种比较好...
Win10系统使用久了,垃圾多了使系统不堪重负,碰上有些恶意软件会修改设置导致系统异常,或者不小心操作修改一些服务都能使系统受伤.当你的系统操作反应越来越慢,或者已经到了瘫痪地步,该如何办?重装?太麻 ...
最新文章
- Spring boot ----RestTemplate学习笔记
- BSP 二叉树再次讨论
- JS getAttribute和setAttribute(取得和设置属性)的使用介绍
- 全面解析并实现逻辑回归(Python)
- linux防火墙配置连接atlas,ATLAS在ubuntu下的安装使用
- mysql导入查询失败_mysql数据库中的查询失败
- html箭头实现流程箭头,js实现带箭头的进度流程
- L2TP详解(五)——Client Initiated隧道和会话建立过程
- 今日头条的针锋相对让腾讯开始焦虑,天天快报能否占据一席之位?
- bat批处理命令:实现读取文件内容,并调用浏览器打开网址,搜索文件内容
- linux比较两个文件的不同
- git .git目录提交_入侵git目录
- 新品上市|A股场内衍生品大盘点
- 购买一台计算机需要哪些配件,组装一台电脑需要哪些配件【详细列举】
- 在VB中如何使IE窗口最大化
- 防止软件进行微信小程序自动刷票、免费投票刷票器手机版的安全设计
- python中的pip命令在cmd下用不了?
- 自回归AR模型、移动平均MA模型与自回归移动平均ARMA模型的比较分析
- Ubuntu16.04配置pytorch环境(CPU版)
- vue子路由跳转问题