写在眼前

写在面前

  在学异步,有位园友推荐了《async in
C#5.0》,没找到汉语版,恰巧也想提升下英文,用我蠢笨的英文翻译一些重点的一对,纯属娱乐,简单分享,保持学习,谨记谦虚。

  在学异步,有位园友推荐了《async in
C#5.0》,没找到中文版,恰巧也想增强下英文,用自身愚蠢的英文翻译一些首要的一些,纯属娱乐,不难分享,保持学习,谨记谦虚。

  若是你以为那件事情没意义翻译的又差,尽情的踩吧。如果你认为值得鼓励,感谢留下您的赞,愿爱技术的园友们在其后每三遍应该可以突破的时候,不拔取知难而退。在每四次应该单独思考的时候,不采用与世浮沉,应该努力的时候,不选取尽量,不辜负每一秒存在的意思。

  借使您以为这件事儿没意义翻译的又差,尽情的踩吧。若是您认为值得鼓励,感谢留下你的赞,愿爱技术的园友们在后来每五遍应该可以突破的时候,不拔取知难而退。在每五遍应该单独思想的时候,不选择趁波逐浪,应该尽力的时候,不选拔尽量,不辜负每一秒存在的意义。

  
转发和爬虫请注脚原文链接http://www.cnblogs.com/tdws/p/5659003.html,博客园
蜗牛 2016年6月27日。

  
转发和爬虫请申明原文链接http://www.cnblogs.com/tdws/p/5659003.html,博客园
蜗牛 2016年6月27日。

图片 1

图片 2

目录

目录

第01章 异步编程介绍

第01章 异步编程介绍

第02章 为啥选取异步编程

第02章 为啥选用异步编程

第03章 手动编写异步代码

第03章 手动编写异步代码

第04章 编写Async方法

第04章 编写Async方法

第05章 Await究竟做了怎么样

第05章 Await究竟做了何等

第06章
以Task为底蕴的异步格局

第06章
以Task为底蕴的异步方式

第07章 异步代码的一些工具

第07章 异步代码的有的工具

第08章 哪个线程在运行你的代码

第08章 哪个线程在运转你的代码

第09章 异步编程中的很是

第09章 异步编程中的格外

第10章 并行使用异步编程

第10章 并行使用异步编程

第11章 单元测试你的异步代码

第11章 单元测试你的异步代码

第12章 ASP.NET应用中的异步编程

第12章 ASP.NET应用中的异步编程

第13章 WinRT应用中的异步编程

第13章 WinRT应用中的异步编程

第14章 编译器在尾部为您的异步做了怎么

第14章 编译器在底层为您的异步做了怎么着

第15章 异步代码的习性

第15章 异步代码的特性

await究竟做了何等?

await究竟做了怎么样?

  我们有二种角度来看待C#5.0的async功用特色,越发是await关键字上暴发了何等:

  大家有三种角度来对待C#5.0的async作用特色,尤其是await关键字上发出了怎么样:

  ·作为一个语言的成效特色,他是一个供您读书的早已定义好的一言一动

  ·作为一个语言的成效特色,他是一个供您读书的早已定义好的行事

  ·作为一个在编译时的转换,那是一个C#语法糖,为了简略从前复杂的异步代码

  ·作为一个在编译时的更换,那是一个C#语法糖,为了简略此前复杂的异步代码

  这都是当真;它们就好像相同枚硬币的两面。在本章,大家将会集中在第一点上来探索异步。在第十四章俺们将会从另一个角度来钻探,即更复杂的,不过提供了部分细节使debug和特性考虑进一步清楚。

  那都是当真;它们如同相同枚硬币的两面。在本章,大家将会集中在率先点上来讨论异步。在第十四章俺们将会从另一个角度来商讨,即更扑朔迷离的,不过提供了有的细节使debug和属性考虑越来越清楚。

休眠和唤醒一个办法

休眠和提醒一个措施

   当您的程序执行碰着await关键字时,我们想要发生两件事:

   当你的程序执行遇到await关键字时,大家想要产生两件事:

  
·为了使您的代码异步,当前举办你代码的线程应该被保释。那代表,在平日,同步的角度来看,你的艺术应该回到。

  
·为了使您的代码异步,当前举办你代码的线程应该被放出。那意味,在平日,同步的角度来看,你的法门应该回到。

  
·当你await的Task完毕时,你的格局应该从此前的职责三番五次,如同它没在早些时候被再次来到。

  
·当你await的Task已毕时,你的主意应该以前边的职位三番五次,就像是它没在早些时候被再次回到。

  为了做到那一个行为,你的不二法门必须在遭逢await时停顿,然后在未来的某个时刻恢复生机执行。

  为了成功这几个行为,你的主意必须在遇见await时停顿,然后在未来的某部时刻复苏执行。

  我把那些进程作为一个休眠一台电脑的小框框情状来看(S4
sleep)。那些办法当前的情景会被积存起来(译者:状态存储起来,正如我们第二章厨房尤其例子,大厨会把已位居烤箱中的食品的烹调状态以标签的款型贴在上边),并且这么些方式完全退出(厨神走了,可能去做任何工作了)。当一台总计机休眠,总结机的动态数据和运行数据被封存到磁盘,并且变得精光关闭。上边那段话和处理器休眠大概一个道理,一个正值await的法门除了用一些内存,不利用别的资源,那么可以视作那个正推行的线程已经被放出。

  我把那一个进度作为一个休眠一台微机的小圈圈情形来看(S4
sleep)。那个点子当前的情形会被贮存起来(译者:状态存储起来,正如大家第二章厨房尤其例子,厨子会把已放在烤箱中的食品的烹调状态以标签的款型贴在地点),并且那几个方法完全脱离(大厨走了,可能去做其余业务了)。当一台电脑休眠,总括机的动态数据和周转数据被保留到磁盘,并且变得完全关闭。上边那段话和电脑休眠大致一个道理,一个正在await的艺术除了用某些内存,不选取任何资源,那么可以视作那些正推行的线程已经被放走。

      
进一步行使类似上一段的类比:一个阻塞型方法更像你暂停一台微机(S3
sleep),它尽管使用较少的资源,但从根本上来讲它平素在运行着。

      
进一步利用类似上一段的类比:一个阻塞型方法更像您暂停一台电脑(S3
sleep),它固然使用较少的资源,但从根本上来讲它一直在运转着。

  在大好的气象下,大家期望编程者察觉不到此地的蛰伏。就算实际上休眠和唤醒一个艺术的中期实施是很复杂的,C#也将会有限协理您的代码被提示,就如什么都没发生同样。(译者:不得不赞誉微软对语法糖的卷入和处理)。

  在非凡的气象下,大家期待编程者察觉不到此处的休眠。即使实际上休眠和提醒一个方式的先前时期实施是很复杂的,C#也将会确保您的代码被唤醒,就像什么都没暴发同样。(译者:不得不赞美微软对语法糖的包裹和拍卖)。

方法的状态

方法的状态

  为了准确的弄精通在您使用await时C#到底为大家做了稍稍工作,我想列出装有有关艺术状态的持有大家记住和询问的细节。

  为了准确的弄领会在您接纳await时C#到底为大家做了有点工作,我想列出装有有关艺术状态的具有我们记住和询问的细节。

  首先,你方法中本地的变量的值会被铭记,包涵以下值:

  首先,你方法中本地的变量的值会被记住,包罗以下值:

  ·你方法的参数

  ·你方法的参数

  ·在本范围内享有你定义的变量

  ·在本范围内装有你定义的变量

  ·其余变量蕴含循环数

  ·其余变量包涵循环数

  ·倘使你的点子非静态,那么包罗this变量。那样,你类的分子变量在章程唤醒时都是可用的。

  ·如若你的措施非静态,那么包含this变量。那样,你类的积极分子变量在点子唤醒时都是可用的。

  他们都被存在.NET
垃圾回收堆(GC堆)的一个对象上。因而当您选拔await时,一个消耗一些资源的对象将会被分配,可是在多数情况下不用担心质量难点。

  他们都被存在.NET
垃圾回收堆(GC堆)的一个对象上。因而当你利用await时,一个消耗一些资源的目的将会被分配,可是在多数景色下不用担心品质难点。

  C#也会记住在点子的怎样地方会履行到await。那可以动用数字存储起来,用来代表await关键字在现阶段格局的职务。

  C#也会记住在章程的怎样地方会实施到await。那可以运用数字存储起来,用来表示await关键字在时下形式的地方。

  在关于怎么样运用await关键字没有何特其余范围,例如,他们可以被用在一个长表明式上,可能蕴含不止一个await:

  在关于怎么样行使await关键字没有啥特其他界定,例如,他们可以被用在一个长表明式上,可能包罗不止一个await:

int myNum = await AlexsMethodAsync(await myTask, await StuffAsync());
int myNum = await AlexsMethodAsync(await myTask, await StuffAsync());

  为了去记住剩余部分的表明式的情形在await某些事物时,增加了附加的原则。比如,当大家运行await
StuffAsync()时,await
myTask的结果要求被铭记。.NET中间语言(IL)在栈上存储那种子类表达式,因此,这么些栈就是我们await关键字须要仓储的。

  为了去记住剩余部分的表达式的情事在await某些事物时,扩展了额外的规范。比如,当我们运行await
StuffAsync()时,await
myTask的结果需求被记住。.NET中间语言(IL)在栈上存储那种子类表明式,因此,这么些栈就是大家await关键字要求仓储的。

  最要害的是,当程序执行到第四个await关键字时,方法便回到了(译者:关于艺术在遇见await时回来,提出读者从第一章拆分的四个法子来通晓)。如果它不是一个async
void方法,一个Task在那个时刻被重回,由此调用者可以等待大家以某种方式成就。C#也必须存储一种操作重回的Task的法子,那样当您的办法成功,那一个Task也变得completed,并且执行者也得以再次回到到方法的异步链当中。确切的建制将会在第十四章中介绍。

  最要紧的是,当程序执行到第二个await关键字时,方法便赶回了(译者:关于艺术在碰到await时回来,指出读者从第一章拆分的五个章程来了然)。假诺它不是一个async
void方法,一个Task在这么些时刻被重返,因而调用者能够等待我们以某种格局成就。C#也务必存储一种操作再次来到的Task的法门,这样当你的章程成功,这一个Task也变得completed,并且执行者也可以回去到格局的异步链当中。确切的体制将会在第十四章中介绍。

上下文

上下文

  作为一个使await的进程尽量透明的一部分,C#捕捉各个上下文在碰着await时,然后在复苏措施使将其回复。

  作为一个使await的经过尽量透明的片段,C#捕捉各个上下文在碰到await时,然后在平复措施使将其死灰复燃。

  在有着工作中最重点的依旧一头上下文(synchronization
context),即能够被用来苏醒措施在一个至极类其余线程上。那对于UI
app越发重点,就是这种只好在不利的线程上操作UI的(就是winform
wpf之类的)。同步上下文是一个繁杂的话题,第八章将会详细解释。

  在所有业务中最要紧的要么一块上下文(synchronization
context),即可以被用于復苏措施在一个特体系型的线程上。那对于UI
app尤其关键,就是那种只能在正确的线程上操作UI的(就是winform
wpf之类的)。同步上下文是一个扑朔迷离的话题,第八章将会详细分解。

  其余项目的上下文也会被从此时此刻调用的线程捕捉。他们的主宰是透过一个均等名称的类来落到实处的,所以我将列出一些关键的前后文类型:

  其余项目的上下文也会被从方今调用的线程捕捉。他们的操纵是经过一个等同名称的类来完毕的,所以自己将列出一些首要的上下文类型:

  ExecutionContext

  ExecutionContext

  那是父级上下文,所有其他上下文都是它的一有些。这是.NET的系统效能,如Task使用其捕捉和扩散上下文,然而它自身不含有怎样作为。

  那是父级上下文,所有其余上下文都是它的一局地。那是.NET的系统效率,如Task使用其捕捉和传颂上下文,可是它本身不带有哪些行为。

  SecurityContext

  SecurityContext

  那是咱们发现并找到平常被界定在当下线程的安全新闻的地点。如若你的代码必要周转在一定的用户,你可能会,模拟或者扮演那几个用户,或者ASP.NET将会帮您兑现扮演。在那种意况下,模拟新闻会存在SecurityContext。

  那是我们发现并找到平常被限定在此时此刻线程的百色音讯的地点。假使您的代码须求周转在特定的用户,你或许会,模拟或者扮演这几个用户,或者ASP.NET将会帮你已毕扮演。在那种状态下,模拟音信会设有SecurityContext。

  CallContext(这么些事物耳熟能详吧,相信用过EF的都领悟)

  CallContext(那个东西耳熟能详吧,相信用过EF的都晓得)

  那允许编程者存储他们在逻辑线程的生命周期中平昔可用的数目。即便考虑到在广大意况下有不佳的显现,它如故可以免止程序中方法的参数传来传去。(译者:因为您存到callcontext里,随时都得以赢得呀,不用通过传参数传来传去了)。LogicalCallContextis是一个有关的可以跨用应用程序域的。

  那允许编程者存储他们在逻辑线程的生命周期中间接可用的数据。即便考虑到在比比皆是场地下有不佳的展现,它仍可以幸免程序中方法的参数传来传去。(译者:因为您存到callcontext里,随时都足以取得呀,不用通过传参数传来传去了)。LogicalCallContextis是一个有关的可以跨用应用程序域的。

      
值得注意的是线程本地存储(TLS),它和CallContext的目标一般,但它在异步的境况下是不工作的,因为在一个耗时操作中,线程被释放掉了,并且可能被用来拍卖任何事情了。你的不二法门也许被升迁并履行在一个不一的线程上。

      
值得注意的是线程本地存储(TLS),它和CallContext的对象一般,但它在异步的景况下是不做事的,因为在一个耗时操作中,线程被放飞掉了,并且可能被用于拍卖其余事情了。你的不二法门恐怕被提示并履行在一个例外的线程上。

  C#将会在你方法苏醒(resume,那里就是一味的“恢复生机”)的时候復苏(restore,我认为那里指从内存中还原)这个品种的上下文。恢复生机上下文将暴发部分支付,比如,一个先后在接纳模拟(此前的上行下效身份之类的)的时候并大方用到async将会变得更慢一些。我提出必变.NET创制上下文的成效,除非你以为那真的有必不可少。

  C#将会在你方法复苏(resume,那里就是一味的“苏醒”)的时候復苏(restore,我认为那里指从内存中还原)那么些类其他上下文。复苏上下文将爆发局地开支,比如,一个先后在接纳模拟(以前的一成不变身份之类的)的时候并大方行使async将会变得更慢一些。我提出必变.NET创设上下文的功效,除非你觉得那确实有必不可少。

await能用在何地?

await能用在哪个地方?

  await可以用在任何标志async的法门和和格局内多数的地点,但是有部分地点你不可能用await。我将分解为啥在一些意况下分歧意await。

  await可以用在其余标记async的法子和和方法内多数的地方,不过有一部分地方你不可能用await。我将表明为何在少数意况下不允许await。

catch和finally块

catch和finally块

  即便在try块中动用await是一心同意的,然则她不允许在catch和finally块中选用。常常在catch和finall块中,非常如故在仓房中未缓解的意况,并且之后将会被抛出。如果await在这些时刻前使用,栈将会有所差异,并且抛出万分的作为将会变得难以定义。

  纵然在try块中利用await是全然同意的,不过他不允许在catch和finally块中运用。平常在catch和finall块中,非凡如故在库房中未缓解的景况,并且之后将会被抛出。尽管await在那一个随时前应用,栈将会有所分裂,并且抛出非凡的行事将会变得难以定义。

  请记住替代在catch块中行使block的格局是在其背后,通过再次来到一个布尔值来记录操作是或不是抛出一个丰盛。示例如下:

  请记住替代在catch块中采取block的法门是在其背后,通过再次回到一个布尔值来记录操作是不是抛出一个可怜。示例如下:

try
{
   page = await webClient.DownloadStringTaskAsync("http://oreilly.com");
}
catch (WebException)
{
   page = await webClient.DownloadStringTaskAsync("http://oreillymirror.com");
}
try
{
   page = await webClient.DownloadStringTaskAsync("http://oreilly.com");
}
catch (WebException)
{
   page = await webClient.DownloadStringTaskAsync("http://oreillymirror.com");
}

   你可以以如下情势代替:

   你可以以如下格局代替:

bool failed = false;
try
{
   page = await webClient.DownloadStringTaskAsync("http://oreilly.com");
}
catch (WebException)
{
   failed = true;
}
if (failed)
{
   page = await webClient.DownloadStringTaskAsync("http://oreillymirror.com");
}
bool failed = false;
try
{
   page = await webClient.DownloadStringTaskAsync("http://oreilly.com");
}
catch (WebException)
{
   failed = true;
}
if (failed)
{
   page = await webClient.DownloadStringTaskAsync("http://oreillymirror.com");
}

  lock块

  lock块

  lock是一种协理编程人士避免其余线程和眼前线程访问同一对象的措施。因为异步代码平常会释放起首实施异步的线程,并且会被回调并且暴发回调在一个不确定的时间量之后,即被放飞掉后和起头的线程差距(译者:固然同样的线程,它也是假释掉之后的了),所以在await上加锁没有其他意义。

  lock是一种支持编程人员避免其余线程和脚下线程访问同一对象的不二法门。因为异步代码经常会自由伊始施行异步的线程,并且会被回调并且发生回调在一个不确定的时间量之后,即被释放掉后和起来的线程不一致(译者:即便同一的线程,它也是自由掉之后的了),所以在await上加锁没有其他意义。

  
在有的景观下,爱戴你的对象不被出现访问是很重大的,不过在并未别的线程在await期间来走访你的对象,使用锁是从未有过必要的。在这个情状下,你的操作是有些冗余的,显式地锁定了三遍,如下:

  
在有些景况下,爱护你的靶子不被出现访问是很重大的,可是在并未其余线程在await时期来做客你的目的,使用锁是向来不需要的。在那个情形下,你的操作是有些冗余的,显式地锁定了五遍,如下:

lock (sync)
{
    // Prepare for async operation
}
    int myNum = await AlexsMethodAsync();
lock (sync)
{
    // Use result of async operation
}
lock (sync)
{
    // Prepare for async operation
}
    int myNum = await AlexsMethodAsync();
lock (sync)
{
    // Use result of async operation
}

  此外,你可以运用一个类库来进行拍卖并发控制,比如NAct,大家将会在第十章介绍

  另外,你能够应用一个类库来进行处理并发控制,比如NAct,大家将会在第十章介绍

  假若您不够幸运,你恐怕要求在实施异步操作时保持某种锁。那时,你就必要搜索枯肠并小心谨慎,因为日常锁住异步调用资源,而不造成争用和死锁是丰硕困难的。也许遭受那种情景想任何办法依然重构你的顺序是最好的挑选。

  借使你不够幸运,你恐怕必要在执行异步操作时保持某种锁。那时,你就必要冥思遐想并小心谨慎,因为一般锁住异步调用资源,而不造成争用和死锁是那么些不方便的。也许碰到那种景色想任何艺术照旧重构你的程序是最好的抉择。

  Linq Query表达式

  Linq Query表达式

  C#有一种语法协理大家尤其便于的去通过书写querys来达到过滤,排序,分组等目标。那一个query可以被执行在.NET平台上或者转换成数据库操作仍旧其他数据源操作。

  C#有一种语法扶助大家进一步便于的去通过书写querys来达到过滤,排序,分组等目标。那几个query可以被实践在.NET平台上或者转换成数据库操作照旧其他数据源操作。

IEnumerable<int> transformed = from x in alexsInts
where x != 9
select x + 2;
IEnumerable<int> transformed = from x in alexsInts
where x != 9
select x + 2;

  C#是在大多数地方是差异目的在于Query表明式中动用await关键字的。是因为这一个地方会被编译成lambda表明式,正因为这么,该lambda表明式必要标记为async关键字。只是那样含蓄的lambda表明式不设有,即便如若确实这么做也会令人confuse。

  C#是在大部职分是不允许在Query表明式中选取await关键字的。是因为这个岗位会被编译成lambda表明式,正因为如此,该lambda表明式必要标记为async关键字。只是那样含蓄的lambda表明式不设有,就算若是实在这么做也会令人confuse。

  我们仍然有措施,你可以写当量的表达式,通过利用Linq内部带的进展方法。然后lambda表明式变得明了可读,继而你也就可以标记他们为async,从而选取await了。(译者:请对照上下代码来阅读)

  我们照旧有方法,你可以写当量的表明式,通过选取Linq内部带的进行方法。然后lambda表达式变得明了可读,继而你也就足以标记他们为async,从而选取await了。(译者:请对照上下代码来读书)

IEnumerable<Task<int>> tasks = alexsInts
.Where(x => x != 9)
.Select(async x => await DoSomthingAsync(x) + await DoSomthingElseAsync(x));
IEnumerable<int> transformed = await Task.WhenAll(tasks);
IEnumerable<Task<int>> tasks = alexsInts
.Where(x => x != 9)
.Select(async x => await DoSomthingAsync(x) + await DoSomthingElseAsync(x));
IEnumerable<int> transformed = await Task.WhenAll(tasks);

  为了收集结果,我使用了Task.WhenAll,那是为Task集合所工作的工具,我将会在第七章介绍细节。

  为了搜集结果,我使用了Task.WhenAll,那是为Task集合所工作的工具,我将会在第七章介绍细节。

  不安全(unsafe)的代码

  不安全(unsafe)的代码

  代码被标记为unsafe的无法包罗await,非安全的代码应该做到那么些少见并且应该保持方法独用和不要求异步。反正在编译器对await做转换的时候也会跳出unsafe代码。(译者:我觉着其实那里并非太在意啦,反正没写过unsafe关键字的代码)

  代码被标记为unsafe的无法包罗await,非安全的代码应该做到那个少见并且应该保证方法独用和不需求异步。反正在编译器对await做转换的时候也会跳出unsafe代码。(译者:我觉着实在那里并非太在意啦,反正没写过unsafe关键字的代码)

破获卓殊

抓获极度

  异步方法的尤其捕获被微软设计的玩命和我们例行同步代码一样的。然则异步的纷纭意味着她们之间还会稍为细微差距。在那里自己将介绍异步怎么样不难的拍卖相当,我也将在第九章详尽讲解注意事项。

  异步方法的不得了捕获被微软设计的尽心和大家健康同步代码一样的。可是异步的繁杂意味着她们之间还会微微细微差异。在那边自己将介绍异步怎么样简单的处理相当,我也将在第九章详细讲解注意事项。

  当耗时操作甘休时,Task类型会有一个概念来表明成功或者战败。最简便易行的就是由IsFaulted属性来向外揭示,在推行进度中生出更加它的值就是true。await关键字将会意识到那或多或少还要会抛出Task中带有的更加。

  当耗时操作停止时,Task类型会有一个定义来声明成功或者退步。最简易的就是由IsFaulted属性来向外揭露,在实践进度中发出至极它的值就是true。await关键字将会发现到那或多或少还要会抛出Task中包含的可怜。

           
就算你熟识.NET很是机制,用也许会担心卓殊的仓库跟踪在抛出相当时怎么正确的保存。那在过去说不定是无法的。但是在.NET4.5中,那么些限制被改动掉了,通过一个叫做ExceptionDispatchInfo的类,即一个合作相当的捕捉,抛出和不利的仓库跟踪的类。

           
如若你熟谙.NET非常机制,用也许会担心极度的堆栈跟踪在抛出极度时怎么正确的保存。这在过去说不定是不容许的。不过在.NET4.5中,那个范围被涂改掉了,通过一个叫做ExceptionDispatchInfo的类,即一个搭档分外的捕捉,抛出和不利的堆栈跟踪的类。

  异步方法也能发现到丰富。在推行异步方法之间爆发别的很是,都不会被捕捉,他们会趁机Task的归来而回到给调用者。当暴发那种情形时,如若调用者在await那么些Task,那么相当将会在这边抛出。(译者:以前有讲到卓殊在异步中会被传送)。在那种措施下,万分通过调用者传播,会形成一个虚构的仓库跟踪,完全如同它暴发在联名代码中千篇一律。

  异步方法也能窥见到不行。在实践异步方法之间暴发其余非常,都不会被捕捉,他们会趁着Task的回到而回到给调用者。当发生那种意况时,借使调用者在await那几个Task,那么非凡将会在此地抛出。(译者:从前有讲到格外在异步中会被传送)。在这种艺术下,至极通过调用者传播,会形成一个虚拟的库房跟踪,完全就像是它发出在联合代码中同样。

           
我把它乘坐虚拟堆栈跟踪,因为堆栈是一个单线程拥有的这么的概念,并且在异步代码中,当前线程实际的仓库和发生相当那个线程的库房可能是十分例外的。十分捕捉的是用户意图中的堆栈跟踪,而不是C#什么抉择执行那些点子的细节。

           
我把它乘坐虚拟堆栈跟踪,因为堆栈是一个单线程拥有的这样的概念,并且在异步代码中,当前线程实际的堆栈和暴发格外那多少个线程的仓库可能是卓殊例外的。非凡捕捉的是用户意图中的堆栈跟踪,而不是C#什么样选取执行那些办法的底细。

直至被必要前异步方法都是一同的

直至被必要前异步方法都是一头的

  我事先说的,使用await只好消费(调用)异步方法。直到await结果发生,这一个调用方法的言语在调用他们的线程中运作,就像是一道方法同样。那非常富有现实意义,尤其是以一个一起的经过做到所有异步方法链时。(译者:当使用await的时候,的确就是安分守纪联合的逐一来推行)

  我以前说的,使用await只好消费(调用)异步方法。直到await结果暴发,这一个调用方法的言语在调用他们的线程中运行,就如一道方法一致。那相当具有现实意义,尤其是以一个一并的历程完结所有异步方法链时。(译者:当使用await的时候,的确就是比照联合的次第来执行)

  还记得以前异步方法暂停在首先次蒙受await时。即使如此,它有时也不须求暂停,因为偶然await的Task已经到位了。一个Task已经被成功的情况如下:

  还记得以前异步方法暂停在率先次遇上await时。即便这样,它有时也不须要暂停,因为有时await的Task已经形成了。一个Task已经被成功的景况如下:

  
·他是被创建落成的,通过Task.FromResult工具方法。大家将会在第七章详细探索。

  
·他是被成立已毕的,通过Task.FromResult工具方法。大家将会在第七章详细探索。

   ·由没境遇async的async方法再次来到。

   ·由没遭逢async的async方法重临。

   ·它运行一个实在的异步操作,可是现在早就做到了(很可能是由于当下线程在遇到await此前早已做了一些事情)。

   ·它运行一个的确的异步操作,不过现在早就形成了(很可能是出于当下线程在遇见await在此以前已经做了少数事情)。

  
·它被一个见面await的asunc方法再次来到,可是所await的这几个前边就早已成功了。

  
·它被一个遇见await的asunc方法再次来到,不过所await的这么些此前就已经到位了。

  由于最终一个可能,一些诙谐的业务暴发在你await一个曾经完成的Task,很可能是在一个纵深的异步方法链中。整个链很像完全同步的。这是因为在异步方法链中,第二个await被调用的法子总是异步链最深的一个。其他的办法到达后,最深的点子才有机会回到。(
The others are only reached after the deepest method has had a chance to
return
synchronously.译者:根据语法来讲我的那句话貌似翻译的不正确,不过本人个人觉得其实情状就是自个儿说的那些样子。在遇到首个await后,前面异步方法链中的await依次执行,逐个重临,最终才回去结果到最深的办法,也就是第二个章程,有哲人来指出那里的理念吗?)

  由于最终一个可能性,一些妙不可言的事情时有发生在您await一个业已成功的Task,很可能是在一个纵深的异步方法链中。整个链很像完全同步的。那是因为在异步方法链中,第二个await被调用的办法总是异步链最深的一个。其他的点子到达后,最深的点子才有空子回到。(
The others are only reached after the deepest method has had a chance to
return
synchronously.译者:依据语法来讲自己的那句话貌似翻译的不科学,可是自己个人觉得实在情况就是自个儿说的那么些样子。在遇见第二个await后,后边异步方法链中的await依次执行,逐个再次回到,最终才再次回到结果到最深的形式,也就是率先个艺术,有哲人来指出那里的视角吗?)

  
你也许会猜忌为何在首先种或第两种情状下还利用async。若是这几个办法承诺平昔联手的回到,你是不利的,并且那样写同步的代码功效超越异步并且没有await的进程。然后,那只是办法同步重返的气象。比如,一个方法缓存其结果到内存中,并在缓存可用的时候,结果可以被一道地回到,不过当它需求异步的互联网请求。当您驾驭有一个好机遇让你利用异步方法,在某种程度上您恐怕还想要方法重返Task或者Task<T>。(异步:既然方法链中有一个要异步,那么就会潜移默化总体都应用异步)。

  
你可能会存疑为何在第一种或第两种情景下还使用async。即使那么些点子承诺一向联手的回来,你是天经地义的,并且那样写同步的代码效指导先异步并且没有await的历程。然后,这只是情势同步再次来到的状态。比如,一个格局缓存其结果到内存中,并在缓存可用的时候,结果可以被一起地回来,不过当它要求异步的网络请求。当你明白有一个好机会让你使用异步方法,在某种程度上您或许还想要方法再次回到Task或者Task<T>。(异步:既然方法链中有一个要异步,那么就会影响全部都使用异步)。

写在结尾

写在最终

  关于异步我还有不少狐疑,也是随着小说逐步驾驭,我也期望能快一些啊。

  关于异步我还有很多迷惑,也是随着小说逐步明白,我也目的在于能快一些啊。

相关文章