第8章 哪个线程运行我的代码

看到社区里的朋友没有翻译完这本书,我接着对一下的章节进行翻译

像我之前说的,异步编程就是关于线程的。那就意味着我们需要理解在C#程序中哪个.NET线程什么时候运行我们的代码,并且当长时间运行的操作发生时线程会发生什么。

在await之前

你写的每一个异步方法中的一些代码将会在await关键字之前。同样,表达式中的一些代码也是等待状态。

这条代码总是运行在调用线程中。在await之前不会发生有意思的事情。

这是关于异步最常见的误解之一。异步从来不会把你的代码放到后台线程去运行。为了这个目的唯一的途径是使用像Task.Run这样的方法。

例如ui应用程序,意味着在await关键字之前的代码运行ui线程,同样在asp.net web应用程序中它运行在asp.net的工作线程中。在这里指的是Task.Run之类的方法。

通常,你可能在包含第一个await的行上运行另外一个async方法作为正在等待的表达式。因为这段表达式是在await之前执行的,它也必须在调用线程中运行。这就意味着调用线程继续在应用程序的深入执行代码,一直到方法中返回Task对象。方法所做的方法可能是一个框架方法,或者是一个使用了TaskCompletionScoure构造的方法。这个方法是应用程序中异步的来源---所有的异步方法只是传递异步。

在到达第一个真正的异步点之前运行的代码可能非常广泛,在ui应用程序中代码都是由ui线程运行的,而ui仍无响应。有希望的是,代码不会话费太长时间,但是重要的是记住:使用异步不能保证ui的响应性。

如果确实感觉到响应速度慢的话,可以使用性能分析器,找到话费时间长的地方。

异步操作期间

哪个线程实际执行了异步操作?

这是一个刁钻的问题。这是异步代码。典型的异步操作像网络请求,没有阻塞的线程去等待操作完成。

当然,如果你使用异步(async)去等待一个计算,比如使用Task.Run,执行计算的线程池线程退出并处于繁忙状态。

有一个线程等待网络请求的完成,但是它在所有网络请求之间是共享的。它被windows上的io完成端口线程调用。当网络请求完成时,操作系统中的中断处理程序会将作业添加到io完成端口的队列中。如果执行1000个网络请求,所有请求都已启动,当响应到达时,它们将由单个io完成端口依次处理。(io完成端口,可自行照看,有机会我会写文章给大家简单说明)

事实上,通常有一些io完成端线程利用多个cpu核。然而线程的数量是相同的无论当前是10个还是1000个未完成的网络请求。

详细介绍同步上下文

同步上下文是由.net framework提供的类,它能在特定类型的线程中运行代码。有各种各样的同步上下文被.net使用,最重要的是被Winform和Wpf所使用的UI线程上下文。

同步上下文的实例没有做任何有用的事情,所以所有实际的实例都是子类。它也有能够让你读取和控制当前异步上下文的静态成员。当前同步上下文是当前线程的一个属性。其思想是在特殊线程中运行的任何时刻,你都能够去获取当前线程并且存储它。之后,你能够在启动的特殊线程上使用它运行代码。只要你能使用同步上下文,并且也能返回,所有这些都是在不需要准确的知道是从哪个线程开始。同步上下文中重要的方法是POST,它能够使委托在正确的上下文中运行。

一些同步上下文能够封装一个线程,像UI线程。有些封装了特殊的线程--例如,线程池---他能够选择其中任何一个线程去发布委托。有些实际上并不改变代码运行在哪个线程上,只是用于检测,就像ASP.NET的

asynchronization context。

等待同步上下文

我们知道你的代码在第一次等待之前是通过调用线程来完成的,但当你的方法恢复等待之后呢?

事实上,大多情况下,它也是通过调用线程来完成的,尽管它在这期间做了其他事。这对开发者来说非常简单了。

C#使用同步上下文去完成这个任务,正如我们之前在本书27页看到的“Con-text”一样,当你等待一个任务的时候,当前同步上下文被作为暂停方法的一部分存储起来。之后当这样的方法被恢复的时候,await关键字的基础结构使用使用POST在捕获的同步上下文中恢复方法。

注意说明:如果像下面这种情况,方法能够在不同的线程上恢复到它开始的地方:

•同步上下文是一个多线程的上下文,比如线程池。

•同步上下文实际上并没有切换线程。

•当await到达的时候当前没有同步上下文,比如一个console应用程序。

•你配置Task不使用同步上下文来恢复。

对于UI应用程序,恢复到相同的线程是最重要的,上面这几点都不重要,所以你可以在等待之后安全的操作你的UI界面。

未完待续。。。

async异步操作和同步上下文的更多相关文章

  1. SynchronizationContext(同步上下文)综述

    >>返回<C# 并发编程> 1. 概述 2. 同步上下文 的必要性 2.1. ISynchronizeInvoke 的诞生 2.2. SynchronizationContex ...

  2. 从执行上下文角度重新理解.NET(Core)的多线程编程[2]:同步上下文

    一般情况下,我们可以将某项操作分发给任意线程来执行,但有的操作确实对于执行的线程是有要求的,最为典型的场景就是:GUI针对UI元素的操作必须在UI主线程中执行.将指定的操作分发给指定线程进行执行的需求 ...

  3. 执行上下文与同步上下文 | ExecutionContext 和 SynchronizationContext

    原文连接:执行上下文与同步上下文 - .NET 并行编程 (microsoft.com) 执行上下文与同步上下文 斯蒂芬 6月15日, 2012 最近,我被问了几次关于 ExecutionContex ...

  4. 使用同步上下文进行C#与VBA代码和Excel之间的交互

    原始出处:www.cnblogs.com/Charltsing/p/RunVBA.html 大家都知道,Excel是个STA,不允许在Excel忙的时候对其Com对象进行操作,也不允许同时有多个线程对 ...

  5. 【C# Task】理解Task中的ConfigureAwait配置同步上下文

    原文:https://devblogs.microsoft.com/dotnet/configureawait-faq/ 作者:Stephen 翻译:xiaoxiaotank 静下心来,你一定会有收获 ...

  6. 【C# TAP 异步编程】四、SynchronizationContext 同步上下文|ExecutionContext

    一.同步上下文(SynchronizationContext)概述 由来 多线程程序在.net框架出现之前就已经存在了.这些程序通常需要一个线程将一个工作单元传递给另一个线程.Windows程序以消息 ...

  7. C#学习笔记之线程 - 同步上下文

    同步上下文(Synchronization Contexts) 手动使用锁的一个替代方案是去声明锁.通过派生ContextBoundObject和应用Synchronization属性,你告诉CLR自 ...

  8. c#同步上下文SynchronizationContext学习笔记

    提供在各种同步模型中传播同步上下文的基本功能.同步上下文的工作就是确保调用在正确的线程上执行. 同步上下文的基本操作 Current 获取当前同步上下文 var context = Synchroni ...

  9. Async 异步转同步详细流程解释

      安装 npm install async --save 地址 https://github.com/caolan/async Async的内容主要分为三部分 流程控制: 简化九种常见的流程的处理 ...

随机推荐

  1. Halcon学习之七:改变图像的现实方式和大小

    change_format ( Image : ImagePart : Width, Height : ) 改变Image图像大小,而且ImagePart图像为灰度值图像. crop_domain ( ...

  2. 「小程序JAVA实战」小程序头像图片上传(上)(43)

    转自:https://idig8.com/2018/09/08/xiaochengxujavashizhanxiaochengxutouxiangtupianshangchuan40/ 在微信小程序中 ...

  3. mybatis No enum const class org.apache.ibatis.type.JdbcType.Date 坑爹的配置

    转自:https://lihaiming.iteye.com/blog/2248059 在ibatis中不需要关注这些参数 而转到mybatis后 如果字段值为空 必须设置jdbcType如inser ...

  4. 03.什么是Lucene全文检索的原理01

    全文检索的原理:查询速度快,精准度高,可以根据相关度进行排序.它的原理是:先把内容分词,分词之后建索引. Lucene是apache下的一个开放源代码的全文检索引擎工具包. 提供了完整的查询引擎和索引 ...

  5. Struts2项目走向流转

    ----------------siwuxie095 Struts2 项目走向流转 1.HTTP 请求流转过程 2.配置文件连接点详解 [made by siwuxie095]

  6. iOS无网络提示或无数据提示空白页

    在我们平常我们用的app当中,当你在信号不好网络错误的时候,一般都会有个提示:“网络错误请点击重试~” 的话术,或者说当你浏览某一页的时候,没有数据,也会提示:“暂无数据,请搞点动静” 之类的话术. ...

  7. NSArray 快速求和、平均值、最大值、最小值

    在iOS开发中我们经常遇到一个需求,求一个数组的所有元素的和,最大值,最小值或者平均值,有的开发者可能第一想到的是for循环遍历求解,其实苹果提供了更简便的方式.如下: NSArray *arr = ...

  8. 8-全排列next_permutation

    C++中全排列函数next_permutation 用法 转载 2017年03月29日 14:38:25 1560 全排列参考了两位的博客 感谢! http://blog.sina.com.cn/s/ ...

  9. Python学习笔记_读Excel去重

    读取一个Excel文件,按照某列关键字,如果有重复则去掉 这里不介绍所有的解决办法,只是列出一个办法. 软件环境: OS:Win10 64位 Python 3.7 测试路径:D:\Work\Pytho ...

  10. Window: move\copy\xcopy

    Move 移动文件和重命名文件与目录. 要移动一个或多个文件: MOVE [/Y | /-Y] [drive:][path]filename1[,...] destination 要重命名目录: MO ...