终于明白了 C# 中 Task.Yield 的用途

最近在阅读 .NET Threadpool starvation, and how queuing makes it worse 这篇博文时发现文中代码中的一种 Task 用法之前从未见过,在网上看了一些资料后也是云里雾里不知其解,很是困扰。今天在程序员节的大好日子里终于想通了,于是写下这篇随笔分享给大家,也过过专心写博客的瘾。

这种从未见过的用法就是下面代码中的 await Task.Yield() :

static async Task Process(){  
 await Task.Yield();  
  var tcs = new TaskCompletionSource<bool>();Task.Run(() =>{Thread.Sleep(1000);tcs.SetResult(true);});tcs.Task.Wait(); }

(注:上面的代码不是示例,只是因为这段代码而初遇 await Task.Yield)

Task.Yield 简单来说就是创建时就已经完成的 Task ,或者说执行时间为0的 Task ,或者说是空任务,也就是在创建时就将 Task 的 IsCompeted 值设置为0。

那 await 一个空任务会怎样?我们知道在 await 时会释放当前线程,等所 await 的 Task 完成时会从线程池中申请新的线程继续执行 await 之后的代码,这本来是为了解决异步操作(比如IO操作)霸占线程实际却用不到线程的问题,而 Task.Yield 却产生了一个不仅没有异步操作而且什么也不干的 Task ,不是吃饱了撑着吗?

今天吃晚饭的时候终于想明白了——吃饱了没有撑。Task.Yield 产生的空任务仅仅是为 await 做嫁衣,而真正的图谋是借助 await 实现线程的切换,让 await 之后的操作重新排队从线程池中申请线程继续执行。这样做有什么好处呢?线程是非常非常宝贵的资源,千金难买一线程,而且有优先级,提高线程利用率的重要手段之一就是及时将线程分配给最需要的地方,而最奢侈的之一是让一个优先级低执行时间长的操作一直占用着一个线程,await Task.Yield 可以让你巧妙地借助 await 的线程切换能力,将不太重要的比较耗时的操作放在新的线程(重新排队从线程池中申请到的线程)中执行。打个比方,很多人排队在外婆家就餐,你来的时候比较巧,正好有位置,但你本来就不着急肚子也不太饿准备慢慢吃慢慢聊,而排队的人当中有些人很饿很着急吃完还有事,这时你如果先点几个招牌菜解解馋,然后将座位让出来,重新排队,并且排队的人当中像你这样的都这么做,那些排队中心急如焚的人真是是幸福感爆棚,外婆家的老板也笑弯了腰。你让出座位重新排队的爱心行为就是 await Task.Yield()

祝大家程序员节快乐!

补充 - 后来发现的相关链接:

  • 出让执行权:Task.Yield, Dispatcher.Yield: https://walterlv.com/post/yield-in-task-dispatcher.html 

原文地址: https://www.cnblogs.com/dudu/p/task-yield.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg

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

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

相关文章

2018-2019 ACM-ICPC, Asia Seoul Regional Contest——A - Circuits

A - Circuits 不难发现x坐标根本没用&#xff0c;只需要存储y坐标。 题目所求的两条直线y1ay_1ay1​a&#xff0c;y2b(a<b)y_2b\ (a<b)y2​b (a<b) 我们枚举y2by_2by2​b这条线&#xff0c;这条线一定可以是矩形的边界&#xff0c;于是我们扫描矩形边界差分计算当前…

aspnet core 2.1中使用jwt从原理到精通一

原理jwt对所有语言都是通用的&#xff0c;只要知道秘钥&#xff0c;另一一种语言有可以对jwt的有效性进行判断;jwt的组成&#xff1b;Header部分Base64转化.Payload部分Base64转化.使用HS256方式根据秘钥对前面两部分进行加密后再Base64转化&#xff0c;其中使用的hs256加密是h…

2020牛客国庆集训派对day3 Points

Points 题目描述 Jack and Rose are playing games after working out so many difficult problems. They together drew a “Haizi” tree to show their collaboration. “Haizi” tree is the same as the tree defined in graph theory. Now Jack would like to count t…

.NET Core微服务之路:利用DotNetty实现一个简单的通信过程

上一篇我们已经全面的介绍过《基于gRPC服务发现与服务治理的方案》&#xff0c;我们先复习一下RPC的调用过程&#xff08;笔者会在这一节的几篇文章中反复的强调这个过程调用方案&#xff09;&#xff0c;看下图根据上面图&#xff0c;服务化原理可以分为3步&#xff1a;服务端…

[译]ASP.NET Core中使用MediatR实现命令和中介者模式

在本文中&#xff0c;我将解释命令模式&#xff0c;以及如何利用基于命令模式的第三方库来实现它们&#xff0c;以及如何在ASP.NET Core中使用它来解决我们的问题并使代码简洁。因此&#xff0c;我们将通过下面的主题来进行相关的讲解。什么是命令模式?命令模式的简单实例以及…

.NET in Browser - Blazor

什么是BlazorBlazor 是一个实验性的. NET web 框架, 使用 C# 和 HTML 在任何浏览器中不需要插件即可运行 WebAssembly 程序集。什么是WebAssemblyWebAssembly是一种新的适合于编译到Web的&#xff0c;可移植的&#xff0c;大小和加载时间高效的格式&#xff0c;是一种新的字节码…

在碰撞中成长 - 北京银行的DevOps实践之路

2018年10/27日&#xff0c;在上海召开的微软年度最大规模的技术盛会—微软2018技术暨生态大会上&#xff0c;北京银行渠道系统负责人&敏捷团队负责人周兵女士和大家一起分享了北京银行的DevOps 实践转型经验&#xff0c;得到了大会听众的热烈评价和共鸣&#xff0c;会后众多…

2020牛客国庆集训派对day4 Emergency Evacuation

Emergency Evacuation 题意&#xff1a; 有n个人在不同的位置上&#xff0c;在最后面有一个出口exit&#xff0c;所有人都要逃离出去&#xff08;走出出口&#xff09;&#xff0c;且每个格子最多容纳一个人&#xff0c;当有人挡在前面时&#xff0c;后面的人必须停留&#x…

【活动(广州)】MonkeyFest2018 微软最有价值专家讲座

MonkeyFest2018微软最有价值专家讲座Monkey Fest 是一个一年一度由全球Microsoft Xamarin跨平台开发者发起的全球性社区活动&#xff0c;主要是推广在云、人工智能、大数据、移动开发等技术。本次活动同时在新加坡&#xff0c;美国&#xff0c;日本&#xff0c;加拿大&#xff…

互联网公司为什么普遍996而不是666

根据skinshoe wu的遭遇&#xff0c;解释一下互联网行业的12小时工作制以及996。题目说的有点绝对&#xff0c;这里先澄清一下&#xff1a;有的公司是10106&#xff0c;9106&#xff0c;10126&#xff0c;995&#xff0c;甚至955&#xff0c;007的都有&#xff0c;我只说大多数&…

IdentityServer4之JWT签名(RSA加密证书)及验签

一、前言在IdentityServer4中有两种令牌&#xff0c;一个是JWT和Reference Token&#xff0c;在IDS4中默认用的是JWT&#xff0c;那么这两者有什么区别呢&#xff1f;二、JWT与Reference Token的区别1、JWT(不可撤回)  JWT是一个非常轻巧的规范&#xff0c;一般被用来在身份提…

.NET Core使用IO合并技巧轻松实现千万级消息推送

之前讲述过多路复用实现单服百万级别RPS吞吐,但在文中有一点是没有说的就是消息IO合并&#xff0c;如果缺少了消息IO合并即使怎样多路复用也很难达到百万级别的请求响毕竟所有应用层面的网络IO读写都是非常损耗性能的&#xff08;需要硬件配置很高的服务器&#xff09;。这一章…

天气情况图像分类练习赛 第三阶段(赛中感)

第三阶段也是实战阶段&#xff0c;不同于前两个阶段的填空而是实打实的预测分析 题目会给出8000张照片数据&#xff0c;其中6000作为训练集而另外2000张作位测试集&#xff0c;通过对6000张的训练来预测2000的结果&#xff0c;并将结果输出到csv文件中&#xff0c;提交检验成功…

一码阻塞,万码等待:ASP.NET Core 同步方法调用异步方法“死锁”的真相

在我们 2015 年开始的从 .NET Framework 向 .NET Core 迁移的工程中&#xff0c;遇到的最大的坑就是标题中所说的——同步方法中调用异步方法发生”死锁”。虽然在 .NET Framework 时代就知道不能在同步方法中调用异步方法&#xff0c;但我们却明知路有坑&#xff0c;偏向此路行…

take

take 题解参考 题目描述 Kanade has n boxes , the i-th box has p[i] probability to have an diamond of d[i] size. At the beginning , Kanade has a diamond of 0 size. She will open the boxes from 1-st to n-th. When she open a box,if there is a diamond in it an…

将传统 ASP.NET 应用迁移到 .NET Core

点击蓝字关注我现在越来越多的人在谈论. NET Core。诚然&#xff0c;.NET Core 是未来, 但是.NET Framework 仍在支持, 因为大量的应用程序无法在短时间内迁移。.NET Core 和 .NET Framework 就像电动汽车和汽油动力汽车。汽油车是成熟的&#xff0c;你可以毫无任何问题驾驶它&…

[翻译] 初看 ASP.NET Core 3.0 即将到来的变化

原文: A first look at changes coming in ASP.NET Core 3.0在我们努力完成下一个 minor 版本的 ASP.NET Core 的同时&#xff0c;我们也在对下一个 major 版本进行更新&#xff0c;其中包括如何使用框架组合项目、更紧密的 .NET Core 集成以及第三方开源集成&#xff0c;所有这…

aspnet core 2.1中使用jwt从原理到精通二

在aspnet core中&#xff0c;自定义jwt管道验证有了上一节的内容作为基础&#xff0c;那这点也是非常容易的&#xff0c;关键点在中间件&#xff0c;只是把上一级在测试类中的自定义验证放到中间件中来即可&#xff0c;不过需要注意&#xff1a;中间件 的位置很重要&#xff0c…

CentOS开发ASP.NET Core入门教程

因为之前一直没怎么玩过CentOS&#xff0c;大多数时间都是使用Win10进行开发&#xff0c;然后程序都部署在Window Server2008或者Window Server2012上&#xff01;因此想尝试下Linux系统。最后经过选型选了比较流行的CentOS系统。正好&#xff0c;今晚要加班&#xff0c;所以在…

工厂参观记:.NET Core 中 HttpClientFactory 如何解决 HttpClient 臭名昭著的问题

在 .NET Framework 与 .NET Core 中 HttpClient 有个臭名昭著的问题&#xff0c;HttpClient 实现了 IDispose 接口&#xff0c;但当你 Dispose 它时&#xff0c;它不会立即关闭所使用的 tcp 连接&#xff0c;而是将 tcp 连接置为 TIME_WAIT 状态&#xff0c;240秒&#xff08;4…