“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”的更多相关文章

  1. task 限制任务数量(转自msdn)

    public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler { // Indicates whether the current ...

  2. 怎么设置task的最大线程数

    //-------------------------------------------------------------------------- // // Copyright (c) Mic ...

  3. C# Task WaitAll和WaitAny

    Task 有静态方法WaitAll和WaitAny,主要用于等待其他Task完成后做一些事情,先看看其实现部分吧: public class Task : IThreadPoolWorkItem, I ...

  4. C# Task ContinueWith的实现

    看了上一篇C# Task 是什么?返回值如何实现? Wait如何实现 我们提到FinishContinuations方法中会调用TaskContinuation实例,那么我们的ContinueWith ...

  5. Asp.Net任务Task和线程Thread

    Task是.NET4.0加入的,跟线程池ThreadPool的功能类似,用Task开启新任务时,会从线程池中调用线程,而Thread每次实例化都会创建一个新的线程.任务(Task)是架构在线程之上的, ...

  6. 走进Task(2):Task 的回调执行与 await

    目录 前言 Task.ContinueWith ContinueWith 的产物:ContinuationTask 额外的参数 回调的容器:TaskContinuation Task.Continue ...

  7. Concepts:Request 和 Task

    当SQL Server Engine 接收到Session发出的Request时,SQL Server OS将Request和Task绑定,并为Task分配一个Workder.在TSQL Query执 ...

  8. .Net多线程编程—任务Task

    1 System.Threading.Tasks.Task简介 一个Task表示一个异步操作,Task的创建和执行是独立的. 只读属性: 返回值 名称 说明 object AsyncState 表示在 ...

  9. nginx+iis+redis+Task.MainForm构建分布式架构 之 (redis存储分布式共享的session及共享session运作流程)

    本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,上一篇分享文章制作是在windows上使用的nginx,一般正式发布的时候是在linux来配 ...

随机推荐

  1. 手把手的教你安装PyCharm --Pycharm安装详细教程(一)(非常详细,非常实用)

    简介 Jetbrains家族和Pycharm版本划分: pycharm是Jetbrains家族中的一个明星产品,Jetbrains开发了许多好用的编辑器,包括Java编辑器(IntelliJ IDEA ...

  2. TCP连接有效性检测方法

    在写TCP服务的时候经常需要面对的问题就是如何知道一个TCP连接当前是否有效,但这个问题对很多初入门的同学来说是很困惑的,主要原因是当对方关闭连接后,另一方无法有效的知道:对于同步操作来说可以通过设置 ...

  3. 深入理解Spring AOP思想

    什么是AOP?AOP解决了什么问题? 在传统的开发模式中,以下层次的是非常常见的一种,业务层每一个方法都要有重复的事务代码 如何改善这个问题? AOP希望将A.B 这些分散在各个业务逻辑中的相同代码, ...

  4. react~props和state的介绍与使用

    props是参数的传递,从上层模块向下层模块进行拿传递:而state是提局域变量,一般在本模块内使用,props是不能改变的,而state可以通过setState去修改自身的值. props Reac ...

  5. C语言程序猿必会的内存四区及经典面试题解析

    前言: 为啥叫C语言程序猿必会呢?因为特别重要,学习C语言不知道内存分区,对很多问题你很难解释,如经典的:传值传地址,前者不能改变实参,后者可以,知道为什么?还有经典面试题如下: #include & ...

  6. REST API设计指导——译自Microsoft REST API Guidelines(一)

    前言 前面我们说了,有章可循,有据可依,有正确的产品流程和规范,我们的工作才不至于产生混乱,团队的工作才能更有成效.我们经常见到,程序开发可能只用了半个月,但是接口的联调却经常需要花费半个月甚至一个月 ...

  7. Java中的定时任务

    现代的应用程序早已不是以前的那些由简单的增删改查拼凑而成的程序了,高复杂性早已是标配,而任务的定时调度与执行也是对程序的基本要求了. 很多业务需求的实现都离不开定时任务,例如,每月一号,移动将清空你上 ...

  8. 【Axios】前端页面使用axios调用后台接口

    项目基本情况 前端项目是用vue.js做的,前端起的服务URL:http://localhost:8080/ 后端项目是用Node.js做的,后端起的服务URL:http://localhost:30 ...

  9. Jenkins结合.net平台之Web项目编译

    前面我们讲解了如何使用msbuild.exe编译一个.net程序.示例中我们讲解的是编译控制台项目,但是我们知道web项目不仅需要编译类的嵌入的资源文件,还要拷贝诸如css,html,js,图片等资源 ...

  10. Python3+Selenium2完整的自动化测试实现之旅(五):自动化测试框架、Python面向对象以及POM设计模型简介

    前言 之前的系列博客,陆续学习整理了自动化测试环境的搭建.IE和Chrome浏览器驱动的配置.selenium-webdriver模块封装的元素定位以及控制浏览器.处理警示框.鼠标键盘等方法的使用,这 ...