码迷,mamicode.com
首页 > 编程语言 > 详细

async in c#5 第八章之哪个线程运行我的异步代码

时间:2019-03-20 01:01:00      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:中断处理   需要   code   asp   基础   margin   size   社区   开发者   

技术图片

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第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 in c#5 第八章之哪个线程运行我的异步代码

标签:中断处理   需要   code   asp   基础   margin   size   社区   开发者   

原文地址:https://www.cnblogs.com/yubabuneng/p/10557229.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!