出让执行权:Task.Yield, Dispatcher.Yield - walterlv,毅仔的博客珠玉在前。同学们可以直接跳转过去看。
比较遗憾的是我没有在里面找到Task.Yield
的合适的应用场景。关于Task.Yield
的应用场景也是争论纷纷,可见这个东西必然很鸡肋。本文尝试了Task.Yield
的几种使用场景,看看是否能够将代码变得更加优雅。
坐在MVP旁边狗尾续貂,诚惶诚恐。。
ReferenceSource里面看到Task.Yield
方法会直接返回一个YieldAwaitable
如果你的代码是这么写
那么此时它将自身线程出让,然后从线程池中拿出一个线程继续执行后续的代码
那么问题来了,什么地方适合使用Task.Yield
1. 单独线程做大规模计算
你可能会想到使用Task.Yield
来开启一个后台线程做大规模计算
但是实际上我们可以使用更加常见的Task.Run
来替代。
大部分情况下上图的两种写法效果是一致的。
那么不一样的地方在哪里呢?第一种写法会在后续的计算中使用同步上下文,而第二种不会
当然如果你在开发WPF程序,而那个耗时计算又是在UI线程上,就可以
选择第一种。
注意:Task.Yield
没有ConfigureAwait
方法,可见其设计目标就是同步上下文的工作情况
2.耗时UI操作,防卡顿
上一小节提出的一种操作场景就是通过Task.Yield
对耗时UI操作进行“切片”,防止卡顿。
但是至少对于WPF程序来说,这里显然有更优的解决方案
或者
在UI线程Dispatcher.Yield
和Task.Yield
是等价的,但是Dispatcher.Yield
额外拥有精细化的优先级控制
3. 它真的很鸡肋,鸡肋到只剩下语法优化
研究之后我坚定了这个方法的鸡肋情况,绞尽脑汁能想到的就只有一些语法层面的简化
例如对于如下的循环中进行简写
这部分的代码简化后还是看着很清晰的
还有一种情况是在接口约束了返回值为Task
的情况下,实现中没有异步时可以使用Task.Yield
满足接口约束
当然你也可以使用Task.FromResult
进行替代
不过这两者存在着是否进行线程切换的细微差别,大部分情况下,更少的线程切换(即Task.FromResult
)是更优的
小结
Task.Yield
可以快速便捷的出让线程的使用权,但是在实际应用上(至少是WPF)缺少较好的使用场景。
参考链接:
- c# – Task.Yield – 真正的用法? - 代码日志
- Dispatcher.Yield – When and how to use it on WinRT – wpdev
- 出让执行权:Task.Yield, Dispatcher.Yield - walterlv
- 终于明白了 C# 中 Task.Yield 的用途 - dudu - 博客园
- c# - When would I use Task.Yield()? - Stack Overflow
- c# - Task.Yield - real usages? - Stack Overflow
- c# - “await Task.Yield()” and its alternatives - Stack Overflow
- Dispatcher.Yield Method (System.Windows.Threading) - Microsoft Docs
- Task.cs
- YieldAwaitable.cs
本文会经常更新,请阅读原文: https://xinyuehtx.github.io/post/%E4%BB%80%E4%B9%88%E6%98%AFtask.yield.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名黄腾霄(包含链接: https://xinyuehtx.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。