C#中Task.Yield的用途深入讲解

作者:dudu 时间:2022-11-12 00:16:23 

前言

最近在阅读 .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()

来源:http://www.cnblogs.com/dudu/p/task-yield.html

标签:c#,task.yield,用途
0
投稿

猜你喜欢

  • 解决Android屏幕四周闪现红框的问题

    2023-09-03 19:17:01
  • Java中使用回调函数的方法实例

    2023-01-28 19:24:21
  • 23种设计模式(12)java模版方法模式

    2021-10-24 11:00:31
  • java使用正则抓取网页邮箱

    2022-12-02 10:30:30
  • Java俄罗斯方块小游戏

    2021-12-01 04:36:49
  • Java方法重载Overload原理及使用解析

    2021-11-21 14:23:14
  • 详解在Spring中如何自动创建代理

    2023-11-15 15:28:52
  • Android高仿微信聊天界面代码分享

    2023-01-23 12:03:03
  • 深入c# GDI+简单绘图的具体操作步骤(三)

    2021-11-27 13:19:55
  • C#编程中设置程序只可被运行一次的方法

    2022-08-09 08:36:32
  • Spring Boot实现热部署的实例方法

    2023-10-24 08:12:50
  • android实现简单左滑删除控件

    2023-11-10 03:01:29
  • 深入java垃圾回收的详解

    2021-11-19 10:33:06
  • Android仿网易新闻图片详情下滑隐藏效果示例代码

    2023-05-31 02:14:03
  • Spring boot通过切面,实现超灵活的注解式数据校验过程

    2022-11-29 07:40:08
  • Android Studio的中文乱码问题解决方法

    2023-06-05 04:48:14
  • 安卓(Android)动态创建多个按钮并添加监听事件

    2023-04-25 16:11:43
  • Android AndBase框架内部封装实现进度框、Toast框、弹出框、确认框(二)

    2022-01-14 12:18:38
  • C#借助OpenCvSharp读取摄像头并显示的实现示例

    2022-12-22 05:49:51
  • Java数据结构之链表、栈、队列、树的实现方法示例

    2021-10-07 10:40:29
  • asp之家 软件编程 m.aspxhome.com