async异步操作和同步上下文
第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异步操作和同步上下文的更多相关文章
- SynchronizationContext(同步上下文)综述
>>返回<C# 并发编程> 1. 概述 2. 同步上下文 的必要性 2.1. ISynchronizeInvoke 的诞生 2.2. SynchronizationContex ...
- 从执行上下文角度重新理解.NET(Core)的多线程编程[2]:同步上下文
一般情况下,我们可以将某项操作分发给任意线程来执行,但有的操作确实对于执行的线程是有要求的,最为典型的场景就是:GUI针对UI元素的操作必须在UI主线程中执行.将指定的操作分发给指定线程进行执行的需求 ...
- 执行上下文与同步上下文 | ExecutionContext 和 SynchronizationContext
原文连接:执行上下文与同步上下文 - .NET 并行编程 (microsoft.com) 执行上下文与同步上下文 斯蒂芬 6月15日, 2012 最近,我被问了几次关于 ExecutionContex ...
- 使用同步上下文进行C#与VBA代码和Excel之间的交互
原始出处:www.cnblogs.com/Charltsing/p/RunVBA.html 大家都知道,Excel是个STA,不允许在Excel忙的时候对其Com对象进行操作,也不允许同时有多个线程对 ...
- 【C# Task】理解Task中的ConfigureAwait配置同步上下文
原文:https://devblogs.microsoft.com/dotnet/configureawait-faq/ 作者:Stephen 翻译:xiaoxiaotank 静下心来,你一定会有收获 ...
- 【C# TAP 异步编程】四、SynchronizationContext 同步上下文|ExecutionContext
一.同步上下文(SynchronizationContext)概述 由来 多线程程序在.net框架出现之前就已经存在了.这些程序通常需要一个线程将一个工作单元传递给另一个线程.Windows程序以消息 ...
- C#学习笔记之线程 - 同步上下文
同步上下文(Synchronization Contexts) 手动使用锁的一个替代方案是去声明锁.通过派生ContextBoundObject和应用Synchronization属性,你告诉CLR自 ...
- c#同步上下文SynchronizationContext学习笔记
提供在各种同步模型中传播同步上下文的基本功能.同步上下文的工作就是确保调用在正确的线程上执行. 同步上下文的基本操作 Current 获取当前同步上下文 var context = Synchroni ...
- Async 异步转同步详细流程解释
安装 npm install async --save 地址 https://github.com/caolan/async Async的内容主要分为三部分 流程控制: 简化九种常见的流程的处理 ...
随机推荐
- jQuery自动触发事件
转自:https://blog.csdn.net/CY_LH/article/details/78982218 常用模拟 有时候,需要通过模拟用户操作,来达到单击的效果.例如在用户进入页面后,就触发c ...
- Java实现主线程等待子线程
本文介绍两种主线程等待子线程的实现方式,以5个子线程来说明: 1.使用Thread的join()方法,join()方法会阻塞主线程继续向下执行. 2.使用Java.util.concurrent中的C ...
- C#枚举最优雅的用法
public enum AbilityLevel { /// <summary> /// Indicates that the individual has a general knowl ...
- Java中异常体系
Java中的异常体系 Throwable,是一个类,表示可抛出的,它是所有的异常都继承的类. Throwable的子类,又分为两种,一种是Error,另一种是Exception. Error一般不是应 ...
- 如何用Elasticsearch实现类似SQL中的IN查询实例
我想实现类似如下sql语句的效果: select * from table1 where rw_id in ('7a482589-e52e-0887-4dd5-5821aab77eea','c68ac ...
- spring是什么
spring是一个容器,用于降低代码间的耦合度,根据不同的代码采用了ioc和aop这二种技术来解耦合. 比如转账操作:a用户少1000,b用户多1000.这是主业务逻辑 IOC 涉及到的事务,日志 ...
- uml 时序图
1.时序图的概念 时序图定义 : 描述了对象之间传递消息的时间顺序, 用来表示用例中的行为顺序, 是强调消息时间顺序的交互图; 时序图描述的事物: 时序图描述系统中类和类之间的交互, 将这些交互建模成 ...
- Oracle中针对中文进行排序
在oracle 9i之前,对中文的排序,是默认按2进制编码来进行排序的. 9i时增加了几种新的选择: 按中文拼音进行排序:SCHINESE_PINYIN_M 按中文部首进行排序:SCHINESE_RA ...
- JavaScript中的一些小技巧
js 数字操作:1.1 取整:取整有很多方法如: parseInt(a,10); Math.floor(a); a>>0; ~~a; a|0; 前面2种是经常用到的,后面3种算是比较偏的, ...
- ajax获取json数据为undefined--原因解析
解决办法:var dataObj=eval("("+data+")");//转换为json对象 问题: 1. 碰到一个问题ajax成功获取json数据后,取值显 ...