第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. IP流量重放与pcap文件格式解析

    (作者:燕云   出处:http://www.cnblogs.com/SwordTao/ 欢迎转载,但也请保留这段声明,谢谢!)   君不见 黄河之水 天上来 奔流到海不复回   君不见 高堂明镜 悲 ...

  2. Redis AOF 全持久化

    简介: Redis AOF 持久化,将每次接收到更改 redis 数据的操作都记录到一个 aof 文件,当服务器意外宕机或 redis 服务器非法关闭时,不会丢失数据. 可以做到数据安全化,但是性能会 ...

  3. 关于struts2.x中(警告: Could not find property [struts.valueStack])的解决方法

    出现“警告: Could not find property [struts.valueStack]”这样的问题,是由于少引用了log4j.jar包,不过,不引用也不影响使用.看个人的爱好了.

  4. Docker入门命令备份

    1.安装Docker curl -sSL https://get.docker.com/ | sh 2.将当前用户加入Docker用户组,这样就不用每次执行docker 命令时加上sudo了 3.查看 ...

  5. 最流行的JavaScript代码规范

    什么是最佳的JavaScript代码编程规范?这可能是一个众口难调的问题.那么,不妨换个问题,什么代码规范最流行? sideeffect.kr通过分析GitHub上托管的开源代码,得出了一些有趣的结果 ...

  6. 第2章地址Address(WCF全面解析3)

    WCF顾明思义,就是在Windows平台下解决通信(C,Communication)的基础框架(F,Foundation)问题. 终结点是WCF最为核心的对象,因为它承载了所有通信功能.服务通过相应的 ...

  7. RedHat Linux设置yum软件源为本地ISO

    先挂载ISO到某个目录下(如我的:/media/RHEL_6.0 x86_64 Disc 1) # mount –o loop rhel-server-6.4-x86_64-dvd.iso /medi ...

  8. 什么是展uv

    uvw是对应三维模型x.y.z坐标,就像模型的皮肤一样,为了便于绘制贴图,需要将UV尽量展平 展UV就是把你建好的模型展开成平面,别人就可以在那平面上做材质,皮肤等,这些东西.例如展一个正方体的UV, ...

  9. react.js 各种小测试笔记

    首先看一个 基础html  至于其中的 js 问价大家去官网下载就好了. <html> <head> <script src="../build/react.j ...

  10. 801. Minimum Swaps To Make Sequences Increasing 为使两个数组严格递增,所需要的最小交换次数

    [抄题]: We have two integer sequences A and B of the same non-zero length. We are allowed to swap elem ...