第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. C#中的四舍五入有多坑

    原文:C#中Math.Round()实现中国式四舍五入 C#中的Math.Round()并不是使用的"四舍五入"法.其实在VB.VBScript.C#.J#.T-SQL中Round ...

  2. 经验总结:WebBrowser自动点击弹出提示框alert、弹出对话框confirm、屏蔽弹出框、屏蔽弹出脚本错误的解决办法

    经验总结:WebBrowser自动点击弹出提示框alert.弹出对话框confirm.屏蔽弹出框.屏蔽弹出脚本错误的解决办法 网上有好多解决方法,可是不一定好使,本人经过多次试验,针对WebBrows ...

  3. 获取properties配置

    1.      使用@Value @Value("${swagger.enable}") 使用Spring的PropertyPlaceholderConfigurer关联 @Val ...

  4. Oracle11gR2导入导出实战之物化视图prebuilt

    源实例上创建表 物化视图 oracle@localhost admin]$ sqlplus system/oracle@orcl2 SQL*Plus: Release 11.2.0.4.0 Produ ...

  5. 选择性导出excel表中内容

    package com.huawei.utils; import java.io.FileNotFoundException;import java.io.FileOutputStream;impor ...

  6. java aop 日志打印 正则设置

    package tz.lion.Utils.aop; import com.alibaba.fastjson.JSON;import org.springframework.web.multipart ...

  7. 【uva1658 算法竞赛入门经典】海军上将【费用流】

    题意 给出一个v(3<=v<=1000)个点e(3<=e<=10000)条边的有向加权图,求1-v的两条不相交(除了起点和终点外没有公共点)的路径,使得权和最小. 分析 费用流 ...

  8. Python实现常见算法[2]——快速排序

    #!/usr/bin/python # module: quik_sort.py def PARTION(L,m,n): base = L[n] i = m-1 j = m while j<n: ...

  9. 用map函数来完成Python并行任务的简单示例

    众所周知,Python的并行处理能力很不理想.我认为如果不考虑线程和GIL的标准参数(它们大多是合法的),其原因不是因为技术不到位,而是我们的使用方法不恰当.大多数关于Python线程和多进程的教材虽 ...

  10. Opencv Laplace算子

    //通过拉普拉斯-锐化边缘 kernel = (Mat_<float>(3,3)<<1,1,1,1,-8,1,1,1,1);//Laplace算子 filter2D(img2, ...