“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. Python内置函数(46)——oct

    英文文档: oct(x) Convert an integer number to an octal string. The result is a valid Python expression. ...

  2. asp.net core 系列 9 环境(Development、Staging 、Production)

    一.在asp.net core中使用多个环境 ASP.NET Core 配置是基于运行时环境, 使用环境变量.ASP.NET Core 在应用启动时读取环境变量ASPNETCORE_ENVIRONME ...

  3. Python爬虫入门教程 16-100 500px摄影师社区抓取摄影师数据

    写在前面 今天要抓取的网站为 https://500px.me/ ,这是一个摄影社区,在一个摄影社区里面本来应该爬取的是图片信息,可是我发现好像也没啥有意思的,忽然觉得爬取一下这个网站的摄影师更好玩一 ...

  4. Android 解压zip文件(支持中文)

    过了n多天后,当再次使用原先博客上写的那篇: Android 压缩解压zip文件 去做zip包的解压的时候,出现了原来没有发现的很多问题.首先是中文汉字问题,使用java的zip包不能很好的解决解压问 ...

  5. Chapter 5 Blood Type——18

    "The Red Cross is having a blood drive in Port Angeles next weekend, so I thought you should al ...

  6. 【深度学习与TensorFlow 2.0】卷积神经网络(CNN)

    注:在很长一段时间,MNIST数据集都是机器学习界很多分类算法的benchmark.初学深度学习,在这个数据集上训练一个有效的卷积神经网络就相当于学习编程的时候打印出一行“Hello World!”. ...

  7. cache2go - cachetable源码分析

    今天我们来看cachetable.go这个源码文件,除了前面介绍过的主要数据结构CacheTable外还有如下2个类型: 下面先看剩下2个类型是怎么定义的: CacheItemPair非常简单,注释一 ...

  8. Mybatis学习(七)————— mybatis的逆向工程的配置详解

    一.什么是逆向工程? 简单点说,就是通过数据库中的单表,自动生成java代码. Mybatis官方提供了逆向工程,可以针对单表自动生成mybatis代码(mapper.java\mapper.xml\ ...

  9. 一文读懂AI简史:当年各国烧钱许下的愿,有些至今仍未实现

    一文读懂AI简史:当年各国烧钱许下的愿,有些至今仍未实现 导读:近日,马云.马化腾.李彦宏等互联网大佬纷纷亮相2018世界人工智能大会,并登台演讲.关于人工智能的现状与未来,他们提出了各自的观点,也引 ...

  10. arcgis api 3.x for js 入门开发系列十叠加 SHP 图层(附源码下载)

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...