.NET 6 新特性 WaitAsync

.NET 6 新特性 WaitAsync

Intro

在 .NET 6 里新增加了一个 WaitAsync 的方法,用来异步地等待一个任务完成,异步等待的时候可以指定一个 Timeout 时间或者一个取消令牌 CancellationToken,在之前的版本中只有一个同步的 Wait 会等待任务的完成,不支持比较好的任务超时或取消处理,如果要实现的话要自己写扩展,很多开源项目甚至微软的项目里会有一个 TimeoutAfter 之类的扩展方法,有了 WaitAsync 之后就可以取代这些扩展了

Definition

新加的 WaitAsync 是一个扩展方法,定义如下:

public static Task WaitAsync(this Task task, TimeSpan timeout);
public static Task WaitAsync(this Task task, CancellationToken cancellationToken);
public static Task WaitAsync(this Task task, TimeSpan timeout, CancellationToken cancellationToken);
// 泛型版本
public static Task<TResult> WaitAsync<TResult>(this Task<TResult> task, TimeSpan timeout);
public static Task<TResult> WaitAsync<TResult>(this Task<TResult> task, CancellationToken cancellationToken);
public static Task<TResult> WaitAsync<TResult>(this Task<TResult> task, TimeSpan timeout, CancellationToken cancellationToken);

Timeout Sample

来看一个 WaitAsync Timeout 的 使用示例:

var tasks = new List<Task>();
tasks.AddRange(new[] 
{ Task.Delay(TimeSpan.FromSeconds(5)),Task.Delay(TimeSpan.FromSeconds(8)),Task.Delay(TimeSpan.FromSeconds(6))
});
Task task = Task.WhenAll(tasks);
try
{await task.WaitAsync(TimeSpan.FromSeconds(3));
}
catch (TimeoutException)
{Console.WriteLine(nameof(TimeoutException));
}
finally
{Console.WriteLine(string.Join(",", tasks.Select(t => t.Status.ToString())));Console.WriteLine(task.Status);
}await Task.Delay(TimeSpan.FromSeconds(5));
Console.WriteLine(string.Join(",", tasks.Select(t => t.Status.ToString())));
Console.WriteLine(task.Status);

上面是一个使用 Timeout 的一个示例,当 Timeout 时间到了之后 Task 还没完成就会 throw 一个 TimeoutException,但是并不会影响原来的任务继续执行,除非自己能够在 exception 的时候将原来的 Task 给中止,上面示例的输出结果如下:

TimeoutException
WaitingForActivation,WaitingForActivation,WaitingForActivation
WaitingForActivation
RanToCompletion,RanToCompletion,RanToCompletion
RanToCompletion

可以看到,即使发生了 Timeout 也不会影响原来 Task 的执行

Cancellation Sample

接着来看一下 CancellationToken 的使用示例

var cts = new CancellationTokenSource();
var tasks = new List<Task>();
tasks.AddRange(new[]
{Task.Delay(TimeSpan.FromSeconds(4)),Task.Delay(TimeSpan.FromSeconds(8)),Task.Delay(TimeSpan.FromSeconds(6))
});
var task = Task.WhenAll(tasks);
try
{cts.CancelAfter(TimeSpan.FromSeconds(5));await task.WaitAsync(cts.Token);
}
catch (TaskCanceledException)
{Console.WriteLine("Task cancelled");
}
finally
{Console.WriteLine(string.Join(",", tasks.Select(t => t.Status.ToString())));Console.WriteLine(task.Status);
}await Task.Delay(TimeSpan.FromSeconds(5));
Console.WriteLine(string.Join(",", tasks.Select(t => t.Status.ToString())));
Console.WriteLine(task.Status);

输出结果如下:

Task cancelled
RanToCompletion,WaitingForActivation,WaitingForActivation
WaitingForActivation
RanToCompletion,RanToCompletion,RanToCompletion
RanToCompletion

使用 CancellationToken 的时候抛出的异常是  TaskCanceledException,而不是前面的 TimeoutException

而抛异常的行为和前面一样,并不会影响原来 Task 的状态

Another Sample

我们再来看一个既使用 Timeout 又使用取消令牌的一个示例吧


try
{await Task.Delay(TimeSpan.FromSeconds(5)).WaitAsync(TimeSpan.FromSeconds(3), CancellationToken.None);
}
catch(Exception ex)
{Console.WriteLine(ex.GetType().Name);
}try
{using var cancellationTokenSource = new CancellationTokenSource();cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(2));await Task.Delay(TimeSpan.FromSeconds(5)).WaitAsync(TimeSpan.FromSeconds(10), cancellationTokenSource.Token);
}
catch(Exception ex)
{Console.WriteLine(ex.GetType().Name);
}

输出结果如下:

TimeoutException
TaskCanceledException

可以看出来哪一个条件 WaitAsync 的条件先满足,抛出的就是哪一个对应的异常,两个异常都没有的就可以正常结束

More

WaitAsync 方法可以解决很多需要等待或者设置 Timeout 的场景,官方支持了这个 API 以后很多 TimeoutAfter/WithCancellationToken 之类的扩展方法可以去掉了

WaitAsync 抛出的异常需要针对处理,如果是 Timeout 则是 TimeoutException 如果是 CancellationToken Cancel 引发的异常则是 TaskCanceledException

References

  • https://github.com/dotnet/runtime/pull/48842

  • https://github.com/dotnet/runtime/blob/v6.0.0-preview.7.21377.19/src/libraries/Common/tests/System/Threading/Tasks/TaskTimeoutExtensions.cs

  • https://github.com/WeihanLi/SamplesInPractice/blob/master/net6sample/WaitAsyncSample/Program.cs

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/299216.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

局域网dos命令集

开启服务命令&#xff1a;net start 服务名信使服务&#xff1a;先开启messenger服务。net send ip "消息文本"局域网dos命令集ls命令是我们常用的几个命令&#xff0c;但是其中有一些很有用的参数我们往往不是很清楚&#xff0c;现在介绍如下&#xff1a; -t -c 按照…

优秀编程网站收录集锦

陆续更新中&#xff0c;敬请关注&#xff1a; 中国开源网&#xff1a;http://www.yuanma.org/ 编程爱好者&#xff1a;http://blog.pfan.cn/vfdff/33993.html 全国嵌入式人才培训基地: http://learn.akae.cn/media/ch21s03.html 转载于:https://www.cnblogs.com/Jessy/archive…

jdbc连接mysql的语法_JDBC连接MySQL

JDBC连接MySQL加载及注册JDBC驱动程序Class.forName("com.mysql.jdbc.Driver");Class.forName("com.mysql.jdbc.Driver").newInstance();JDBC URL定义驱动程序与数据源之间的连接标准语法&#xff1a;::MySQL的JDBCURL格式&#xff1a;jdbc:mysql//[hostna…

被评为“影响世界千年的物理学家”,杨振宁的伟大,你根本不了解

全世界只有3.14 % 的人关注了爆炸吧知识2018年3月14日&#xff0c;英国科学家霍金去世&#xff0c;作为当代英国最杰出的科学家之一&#xff0c;英国用最规格的方式送别了这位伟大的科学家。霍金去世了&#xff0c;中国媒体沸腾了&#xff01;有人说&#xff1a;这是全人类的损…

[1197]约瑟夫问题 (循环链表)SDUT

约瑟夫问题 Time Limit: 1000ms Memory limit: 65536K 有疑问&#xff1f;点这里^_^ 题目描述 n个人想玩残酷的死亡游戏&#xff0c;游戏规则如下&#xff1a; n个人进行编号&#xff0c;分别从1到n&#xff0c;排成一个圈&#xff0c;顺时针从1开始数到m&#xff0c;数到m…

Blazor+Dapr+K8s微服务之服务调用

1.1 Dapr环境配置1.1.1 在开发机安装Docker Desktop并启用Kubernetes安装过程略&#xff0c;安装好后效果如下&#xff1a;&#xff08;左下角两个绿色指示Docker和K8s正在运行&#xff09;1.1.2 在开发机安装Dapr Cli安装命令&#xff1a;powershell -Command …

squid2.6加速WEB支持虚拟主机配置心得体会 .txt

人一台web服务器&#xff0c;日流量约10万&#xff0c;上面有好几个虚拟主机&#xff0c;近日装上Squid 2.6进行WEB加速&#xff0c;Squid 和Apache均在同一台服务器上面&#xff0c;效果非常明显&#xff0c;看到论坛上好多人问如何配置squid2.6支持,虚拟主机现在将安装过程贴…

IT职涯路

在51cto周刊上发现了这篇文章&#xff0c;不错&#xff0c;转载过来~~ 前段时间看了一篇文章&#xff0c;叫做《IT人为什么难以拿高薪》&#xff0c;颇有感触&#xff0c;于是写下这篇文章&#xff0c;希望与各位XDJM共勉&#xff5e; 能够看到这个帖子的每个XDJM&#xff0c;…

mysql 卸载插件_MySQL 插件安装或卸载(window validate_password 为例)

查看插件&#xff1a;mysql> show plugins;mysql> select plugin_name,plugin_status,plugin_type,load_option,plugin_library from information_schema.plugins;默认插件目录&#xff1a;mysql> show variables like plugin_dir;----------------------------------…

11部高分学科纪录片,助力孩子涨姿势拓视野~

全世界只有3.14 % 的人关注了爆炸吧知识▌导读本文为同学们整理了11部高分经典学科纪录片&#xff0c;对应文学、数学、经济学、地理、化学、生物、物理、历史、社会学、美学、天文学11个学科。这不仅是课堂学习的补充与延伸&#xff0c;更是开拓视野、激发学习内驱力的绝佳利器…

Istio 首次安全评估结果公布

本文译自 Istio 社区官方博客 Announcing the results of Istio’s first security assessment[1]&#xff0c;作者 Neeraj Poddar&#xff0c;译者宋净超。Istio 服务网格已在各行各业获得广泛的生产应用。该项目的成功&#xff0c;以及其在基础设施中执行关键安全策略的重要用…

mile for gallon 汽车省油

计算汽车省油&#xff0c;用英里每加仑比较&#xff0c;允许重复比较//mile for gallon 汽车省油 #include<iostream>const double GALLON 0.264179; double milepergallon(double kilo,double mile);int main() {using namespace std;double kilo[2],mile[2],milebygal…

使用C#制作简易的注册表编辑器

本文节选自《21天学通C#》一书 下面来实现一个简易的注册表编辑器。它具备了Windows操作系统自带的注册表编辑器的一般功能。如示例代码19-7所示。示例代码19-7主窗体。主窗体在启动时&#xff0c;会在加载事件中加载注册表到树形控件中&#xff0c;就像在Windows操作系统中…

世博游览技巧

世博游览技巧 方案一&#xff1a; 一日进园 步骤1&#xff1a;4:50-5:30到达5号门3号口 07:00开园后最大速度向后面的安检口跑 看到少于30人就可以拿到中国的预约&#xff08;也就是安检的前3排&#xff09; 09:00安检后就会有人发中国的预约券&#xff08;可以不按预约的时间…

node 16位 转24位_同时将24位和32位BMP图像顺时针旋转90度

上一次我们将24位的皮卡丘旋转了90度&#xff0c;但是后来改需求了。。。要求把32位的.bmp文件也能够旋转90度。上次就懵逼的我继续懵逼&#xff0c;只好继续转向CSDN求助。浏览了各种求助帖&#xff08;还找到了数年前的信科大一学长&#xff09;&#xff0c;终于发现了32位和…

这几个关乎我们一生教养的原则,每个人都应该知道。

▲ 点击查看最近刷到这样两条微博&#xff0c;让人心头一暖。一条是杭州一个小男孩给医院捐款千元&#xff0c;还附上了一封感谢信。临走时还给医生敬了个少先队礼。另一条是扬州一名女孩把自己的小黄鸭储蓄罐整个捐到派出所&#xff0c;留下一张写着“武汉加油”的纸条&#x…

莫名其妙的主机名 VM_32_234_centos

在腾讯服务器上部署的时候出现的莫名其妙的错误, 我在配置文件上都写 master, node1, 但是运行mapredure的时候的时候老是出现 Job job_1409546978133_0001 failed with state FAILED due to: Application application_1409546978133_0001 failed 2 times due to Error launc…

如何通过提问成为更好的开发人员

如何通过提问成为更好的开发人员这是新的一年的开始&#xff0c;所以我想以一篇我已经计划写了一段时间但从未真正开始创作的帖子开始。我最近开始了一份新工作&#xff0c;加入Elastic[1]&#xff0c;负责开发他们的 .NET 语言客户端。因此&#xff0c;最终将这个主题编写并发…

生活经典名句

&#xff11;&#xff0c;记住该记住的&#xff0c;忘记该忘记的。改变能改变的&#xff0c;接受不能改变的 &#xff12;&#xff0c;能冲刷一切的除了眼泪&#xff0c;就是时间&#xff0c;以时间来推移感情&#xff0c;时间越长&#xff0c;冲突越淡&#xff0c;仿佛不断稀释…

转载 一篇UI规范文件

这是一个UI模板规范&#xff0c;在做B/S版应用程序时比较适用&#xff0c;其实这样的东西算不上什么正规的规范&#xff0c;只是为了适应我们现在面对的开发环境和组织流程做的一些权宜的努力&#xff0c;和解决了一些与程序沟通和接口的问题&#xff0c;尽量避免误会和摩擦。 …