dotnet 警惕 Task 的 ContinueWith 带上 OnlyOnFaulted 参数抛出取消异常
本文记录 dotnet 的一个令人迷惑的设计,在 Task 里,有一个叫 ContinueWith 的方法,此方法可以在 Task 完成时执行传入的委托。在 ContinueWith 方法里面,还有一个可选的 TaskContinuationOptions 参数,在此参数里面传入 OnlyOnFaulted 即可在 Task 出错时才执行传入的委托,然而此行为迷惑的是在 Task 正在执行完成却抛出取消异常
在等待任务执行完成之后,干某个活的事情上,有多个可选方法。一个就是老实使用 await 等待 Task 执行完成,然后再继续编写后续逻辑,如以下代码
await task;
干自己的活();
另一个方法就是通过 ContinueWith 方法,比如在使用 Task.Run 执行某个 Foo 方法之后,再 干自己的活 的代码
var task = Task.Run(Foo).ContinueWith(t =>
{
});
以上的 ContinueWith 方法里面传入的委托是不管 Task 的执行状态,无论是成功还是失败都能进入。如果只期望只有在失败时才进入,可以传入 OnlyOnFaulted 参数,代码如下
var task = Task.Run(Foo).ContinueWith(t =>
{
}, TaskContinuationOptions.OnlyOnFaulted);
然而这里存在一个令人迷惑的行为,大家猜猜,当 Foo 正常执行时,等待上面代码的 task 时,是否会抛出异常
答案是抛出 TaskCanceledException 异常
var task = Task.Run(Foo).ContinueWith(t =>
{
}, TaskContinuationOptions.OnlyOnFaulted);
try
{
await task;
}
catch (TaskCanceledException e)
{
}
static void Foo()
{
}
这是因为 dotnet 认为 ContinueWith 里面的委托被取消了
那如果 Task 执行过程中抛出异常呢?看看下面的代码
var task1 = Task.Run(FooWithException).ContinueWith(t =>
{
}, TaskContinuationOptions.OnlyOnFaulted);
await task1;
static void FooWithException()
{
throw new Exception("lindexi is doubi");
}
可以看到 task1 正常被等待,啥事都没有发生
这么特别诡异起来了,很好就在代码里面挖坑。毕竟写了以上代码的开发者更多的是进行测试 Task 异常的情况。再加上如果偶尔的正常执行完成,抛出的是取消异常,很多开发者都会以为是正常被取消而已
也有伙伴说,那分开两个 Task 等待好了,如以下代码
var task = Task.Run(Foo);
var task1 = task.ContinueWith(t =>
{
}, TaskContinuationOptions.OnlyOnFaulted);
但是以上代码解决不了的问题是,如果期望等待整个大的 Task 执行完成,也就是 Task 和 ContinueWith 里面的内容全部执行完成,那这个逻辑就诡异了
也就是只有在无需等待 ContinueWith 执行结果的情况下,才可以推荐使用 OnlyOnFaulted 参数。没有等待 ContinueWith 执行结果,且刚好 Task 是正常执行的,这是不会将取消异常抛到 UnobservedTaskException 里的
TaskScheduler.UnobservedTaskException += (sender, eventArgs) =>
{
};
在 dotnet 的设计里面,如果一个 Task 存在异常,且这个 Task 的异常没有被任何代码捕获到,将在此 Task 被 GC 时,抛到 UnobservedTaskException 里面。可以通过如上代码的事件,获取到是否存在有 Task 的异常没有被捕获。进入 UnobservedTaskException 事件的异常不会导致应用挂掉,只是用来记录日志或者埋点上报等,让开发者知道有某个 Task 的异常没有被捕获
可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin f758059f3f9f9bbfe2e7205a137d2e5b3da31f7a
以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin f758059f3f9f9bbfe2e7205a137d2e5b3da31f7a
获取代码之后,进入 HojohoyahobaWayfahurhalqeje 文件夹
更多博客,请参阅我的 博客导航
dotnet 警惕 Task 的 ContinueWith 带上 OnlyOnFaulted 参数抛出取消异常的更多相关文章
- js进阶解决浏览器缓存不能自动更新的问题(在ajax的url上带上一个参数,可以是日期,或者是随机数)(随机数Math.random)(取得日期的毫秒数:new Date().getTime();)
js进阶解决浏览器缓存不能自动更新的问题(在ajax的url上带上一个参数,可以是日期,或者是随机数)(随机数Math.random)(取得日期的毫秒数:new Date().getTime();) ...
- 在XP系统中自带的 msvcrt.dll 和 Vista 中的 msvcrt.dll 版本不同,导致抛出的异常不同
然而,在XP系统中,系统自带的 msvcrt.dll 和 Vista 中的 msvcrt.dll 版本不同, 并没有这个 _except_handler4_common ,结果就出现了启动程序时,遇到 ...
- 记一次asp.net core 在iis上运行抛出502.5错误
asp.net core 在iis上运行抛出502.5异常的部分原因以及解决方案 环境说明 已安装 .net core runtime 2.1.401 已安装 .net core windows ho ...
- 调用远程主机上的 RMI 服务时抛出 java.rmi.ConnectException: Connection refused to host: 127.0.0.1 异常原因及解决方案
最近使用 jmx 遇到一个问题,client/server 同在一台机器上,jmx client能够成功连接 server,如果把 server 移植到另一台机器上192.168.134.128,抛出 ...
- 案例复现,带你分析Priority Blocking Queue比较器异常导致的NPE问题
摘要:本文通过完整的案例复现来演示在什么情况会触发该问题,同时给出了处理建议.希望读者在编程时加以借鉴,避免再次遇到此类问题. 本文分享自华为云社区<Priority Blocking Queu ...
- Asp.net Core dotnet 发布类库文件 带上注释,发布预发行版,带上所有引用
带上注释 效果图 带上所有引用 效果图 预发行版 效果图 由于微软取消了 project.json 这个json 转而用了csproj 用于保存配置 所以懵逼很大一会 资料来源 project.j ...
- 【HDU 4940】Destroy Transportation system(无源无汇带上下界可行流)
Description Tom is a commander, his task is destroying his enemy’s transportation system. Let’s repr ...
- .NetCore HttpClient发送请求的时候为什么自动带上了一个RequestId头部?
奇怪的问题 最近在公司有个系统需要调用第三方的一个webservice.本来调用一个下很简单的事情,使用HttpClient构造一个SOAP请求发送出去拿到XML解析就是了. 可奇怪的是我们的请求在运 ...
- 记得ajax中要带上AntiForgeryToken防止CSRF攻击
经常看到在项目中ajax post数据到服务器不加防伪标记,造成CSRF攻击 在Asp.net Mvc里加入防伪标记很简单在表单中加入Html.AntiForgeryToken()即可. Html.A ...
- ZOJ 2314 带上下界的可行流
对于无源汇问题,方法有两种. 1 从边的角度来处理. 新建超级源汇, 对于每一条有下界的边,x->y, 建立有向边 超级源->y ,容量为x->y下界,建立有向边 x-> 超级 ...
随机推荐
- 新零售SaaS架构:线上商城系统架构设计
零售商家为什么要建设线上商城? 传统的实体门店服务范围有限,只能吸引周边500米以内的消费者.因此,如何拓展服务范围,吸引更多的消费者到店,成为了店家迫切需要解决的问题. 缺乏忠实顾客,客户基础不稳, ...
- Jmeter的Throughput有误差与分布式测试时的坑
我是两台压力机,分布式启动jmeter压测180秒,结果throughput显示3075,我用总请求数/总耗时,64万左右/180秒,得到的TPS是3500左右.误差17% 网上说jmeter的thr ...
- multisim的支路及总线设计
Multisim的支路及总线设计 1.实验原理 最近在使用multisim设计时,用到了总线和支路设计,这里记录一下,方便以后查阅相关操作.其中主要是总线的使用和支路连接器的使用. 2.实验操作 (1 ...
- 浅谈JVM整体架构与调优参数
本文分享自华为云社区<[性能优化]JVM整体架构与调优参数说明>,作者: 冰 河. JVM的分类 这里,我们先来说说什么是VM吧,VM的中文含义为:虚拟机,指的是使用软件的方式模拟具有完整 ...
- #根号分治,树上倍增#洛谷 3591 [POI2015]ODW
题目 分析 考虑直接用倍增跳会TLE,设\(f[x][i]\)表示以\(x\)为起点每次跳\(i\)步的点权和, 这可以预处理出来,综合一下两种做法,当\(i>\sqrt{n}\)时直接上倍增, ...
- #模拟#U137456 数字
题目 牛牛和他的小伙伴们高高兴兴的吃完了蛋糕,吃完蛋糕之后就到了牛牛和他的小伙伴们最喜欢的环节了--猜数 字, 这次是牛牛的生日,大家决定让牛牛来制定规则,由于牛牛的生日是4月7日,所以牛牛特别喜欢数 ...
- OpenHarmony社区运营报告(2023年8月)
本月快讯 ● 2023年8月3日,OpenAtom OpenHarmony(以下简称"OpenHarmony")发布了Beta2版本.OpenHarmony 4.0 Beta2 ...
- 文档贡献与写作必读-OpenHarmony开发者文档风格指南
在您使用OpenHarmony文档或参与OpenHarmony文档/生态内容贡献时,是否遇到过如下问题: ● 应该使用第一人称还是第二人称来写作? ● Markdown文件应该如何命名? ● 代码块及 ...
- XML文档节点导航与选择指南
XPath(XML Path Language)是XSLT标准的主要组成部分.它用于在XML文档中浏览元素和属性,提供了一种强大的定位和选择节点的方式. XPath的基本特点 代表XML路径语言: X ...
- ssm 创建bean的三种方式和spring依赖注入的三种方式
<!--创建bean的第一种方式:使用默认无参构造函数 在默认情况下: 它会根据默认无参构造函数来创建类对象.如果 bean 中没有默认无参构造函数,将会创建失败--> <bean ...