Task.Wait and “Inlining”
“What does Task.Wait do?”
Simple question, right? At a high-level, yes, the method achieves what its name implies, preventing the current thread from making forward progress past the call to Wait until the target Task has completed, one way or another. If the Task ran to completion, Wait will return successfully. If the Task completed due to faulting or being canceled, it will throw an exception indicating the relevant details (since the waiting code likely expects that all work to be completed by the task ran successfully if Wait returns successfully).
The details are a bit more interesting. Wait could simply block on some synchronization primitive until the target Task completed, and in some cases that’s exactly what it does. But blocking threads is an expensive venture, in that a thread ties up a good chunk of system resources, and a blocked thread is dead weight until it’s able to continue executing useful work. Instead, Wait prefers to execute useful work rather than blocking, and it has useful work at its finger tips: the Task being waited on. If the Task being Wait’d on has already started execution, Wait has to block. However, if it hasn’t started executing, Wait may be able to pull the target task out of the scheduler to which it was queued and execute it inline on the current thread.
To do that, Wait asks for assistance from the target scheduler, by making a call to the TaskScheduler’s TryExecuteTaskInline method. TryExecuteTaskInline can do whatever logic the scheduler needs in order to validate that the current context is acceptable for inlining the Task. If it is, the scheduler tries to execute the task then and there as part of the call to TryExecuteTaskInline (using the base TaskScheduler’s TryExecuteTask method) and returns whether the Task could be executed. If it couldn’t be executed in TryExecuteTaskInline, the scheduler returns false, and Wait will need to block until the Task completes. A Task may not be able to be executed if it’s already been or is currently being executed elsewhere. As an example of this, the default scheduler (based on the ThreadPool) is aggressive about inlining, but only if the task can be efficiently removed from the data structures that hold tasks internally in the ThreadPool (such as if the task is living in the local queue associated with the thread attempting to inline it).
This is also very similar to what happens when Task.RunSynchronously is used to execute a Task (RunSynchronously may be used instead of Task.Start to run a Task currently in the TaskStatus.Created state). RunSynchronously results in the Framework calling the target scheduler’s TryExecuteTaskInline, allowing the scheduler to decide whether to inline or not. If the scheduler chooses not to inline, the Task will instead be queued to the scheduler, and the system will block until the Task is completed.
Of course, schedulers may want to behave differently depending on whether the code is explicitly choosing to inline (e.g. RunSynchronously) or whether the inlining is happening implicitly (e.g. Wait). To support this difference, in addition to accepting as a parameter the Task to be inlined, TryExecuteTaskInline also accepts as a parameter a Boolean taskWasPreviouslyQueued. This value will be false if it is known that the specified task has not yet been submitted to the scheduler, and true otherwise. If RunSynchronously is being used, taskWasPreviouslyQueued will be false; if Wait, it will be true. The default scheduler does, in fact, differentiate between these two cases, in that it always supports explicit inlining through RunSynchronously.
原文:https://devblogs.microsoft.com/pfxteam/task-wait-and-inlining
Task.Wait and “Inlining”的更多相关文章
- task 限制任务数量(转自msdn)
public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler { // Indicates whether the current ...
- 怎么设置task的最大线程数
//-------------------------------------------------------------------------- // // Copyright (c) Mic ...
- C# Task WaitAll和WaitAny
Task 有静态方法WaitAll和WaitAny,主要用于等待其他Task完成后做一些事情,先看看其实现部分吧: public class Task : IThreadPoolWorkItem, I ...
- C# Task ContinueWith的实现
看了上一篇C# Task 是什么?返回值如何实现? Wait如何实现 我们提到FinishContinuations方法中会调用TaskContinuation实例,那么我们的ContinueWith ...
- Asp.Net任务Task和线程Thread
Task是.NET4.0加入的,跟线程池ThreadPool的功能类似,用Task开启新任务时,会从线程池中调用线程,而Thread每次实例化都会创建一个新的线程.任务(Task)是架构在线程之上的, ...
- 走进Task(2):Task 的回调执行与 await
目录 前言 Task.ContinueWith ContinueWith 的产物:ContinuationTask 额外的参数 回调的容器:TaskContinuation Task.Continue ...
- Concepts:Request 和 Task
当SQL Server Engine 接收到Session发出的Request时,SQL Server OS将Request和Task绑定,并为Task分配一个Workder.在TSQL Query执 ...
- .Net多线程编程—任务Task
1 System.Threading.Tasks.Task简介 一个Task表示一个异步操作,Task的创建和执行是独立的. 只读属性: 返回值 名称 说明 object AsyncState 表示在 ...
- nginx+iis+redis+Task.MainForm构建分布式架构 之 (redis存储分布式共享的session及共享session运作流程)
本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,上一篇分享文章制作是在windows上使用的nginx,一般正式发布的时候是在linux来配 ...
随机推荐
- ThinkPHP 数据库操作(六) : 查询事件、事务操作、监听SQL
查询事件 查询事件(V5.0.4+) 从 5.0.4+ 版本开始,增加了数据库的CURD操作事件支持,包括: 查询事件仅支持 find . select . insert . update 和 del ...
- Python内置函数(64)——tuple
英文文档: The constructor builds a tuple whose items are the same and in the same order as iterable‘s it ...
- 前两天做项目遇到了sqlserver最大连接数 Max Pool Size 的问题
前言:出现这种问题使因为程序对connection的回收出现了问题,是因为你的代码出出现了过多new connection(),这种情况还是你的代码问题,如果不想把问题归根于程序,那你就可以改变con ...
- MyBatis 分页插件 PageHelper 使用
1. 引入Maven依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&qu ...
- java基础(四)-----抽象类与接口
抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念的支持有很大的相似,甚至可以互换,但是也有区别. 一.抽象类 我们 ...
- Python爬虫入门教程 29-100 手机APP数据抓取 pyspider
1. 手机APP数据----写在前面 继续练习pyspider的使用,最近搜索了一些这个框架的一些使用技巧,发现文档竟然挺难理解的,不过使用起来暂时没有障碍,估摸着,要在写个5篇左右关于这个框架的教程 ...
- 初学Java Web(5)——cookie-session学习
HTTP 协议 Web 浏览器与 Web 服务器之间的一问一答的交互过程必须遵守一定的规则,这样的规则就是 HTTP 协议. HTTP 是 hypertext transfer protocol(超文 ...
- Java开发知识之JAVA的反射
目录 Java中的反射机制 一丶什么是反射机制 二丶Class类,自描述类.获取类名的三种方法 1.使用静态属性Class获取 2.使用Class方法 forName()获取自描述Class 3.使用 ...
- iframe跨域通信实战
"长时间不写文章,开头的方式总是那么出奇的相似",最近很忙,好久没写博客了啊(是不是?). 更换工作已经有三个月有余,这段三个月把过去三年没加过的班都加了一次.收获挺多,发现的问题 ...
- babel版本兼容报错处理:Plugin/Preset files are not allowed to export objects
原文地址: https://www.cnblogs.com/jiebba/p/9618930.html 1.为什么会报错 ? 这里抱着错误是因为 babel 的版本冲突. 多是因为你的 babel 依 ...