异步编制程序种类第03章 本身写异步代码

当前位置: 钱柜手游app > 成人娱乐 >

写在前面

  在学异步,有位园友推荐了《async in C#5.0》,没找到粤语版,赶巧也想巩固下日文,用本身粗笨的意国语翻译一些人命关天的有些,纯属娱乐,轻便分享,保持学习,谨记谦逊。

  即便您以为那事儿没意义翻译的又差,尽情的踩吧。纵然你以为值得鼓劲,感谢留下您的赞,愿爱才能的园友们在之后每趟应该能够突破的时候,不选用打退堂鼓。在每叁次应该单独观念的时候,不接收与世起落,应该尽力的时候,不选拔尽量,不辜负每大器晚成秒存在的意义。

   转载和爬虫请表明原来的作品链接,博客园 蜗牛 2016年6月27日。

目录

第01章 异步编制程序介绍

第02章 为何使用异步编制程序

第03章 手动编写异步代码

    .NET中的一些异步形式
    最简易的异步格局
    关于Task的介绍
    手动编写异步代码的主题素材
    行使手写异步代码转变示例(第二章结尾一个示范)

第04章 编写Async方法

第05章 Await毕竟做了如何

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

第07章 异步代码的风度翩翩对工具

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

第09章 异步编制程序中的分外

第10章 并行使用异步编制程序

第11章 单元测量检验你的异步代码

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

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

第14章 编写翻译器在尾部为你的异步做了什么

第15章 异步代码的品质

手动编写异步代码

  在本章,大家将商批评一些关于不使用C#5.0首要字async的异步编制程序。这种方法即便早正是过去的本事,大概你不会再选择,但这对于你知道异步编制程序表象背后产生了哪些业务是很注重的。也因为这点,作者将会火速的描述示例,仅仅器重揭穿出对你掌握有扶持的地点。

 

.NET中的一些异步格局

  正如本身事情发生前涉嫌的,Silverlight只提供了像web访问的异步版本API。这里有一个事例,你能够下载叁个网页,并体现它:

private void DumpWebPage(Uri uri)
{
WebClient webClient = new WebClient();
webClient.DownloadStringCompleted += OnDownloadStringCompleted;
webClient.DownloadStringAsync(uri);
}
private void OnDownloadStringCompleted(object sender,
DownloadStringCompletedEventArgs eventArgs)
{
m_TextBlock.Text = eventArgs.Result;
}

  这种API是依照事件的异步方式(EAP)。这几个主见是想替代单线程方法去下载网页,即拥塞型代码会一向等到下载结束再调用二个方法或接触三个事变。那个法子看起来和协作代码相仿,除了无重临类型。这么些事件也可以有三个专程的eventArgs类型,它蕴含值检索。

  大家在调用那么些点子前注册了平地风波。该方法马上重返,当然那是因为它是异步代码。然后在以往的某部时刻触发。这种方式分明很复杂,不唯有是因为您要将它分为像例子同样的八个法子。最要紧的是,你注册了一个时日净增了复杂。假如说小编还要用同意气风发的WebClient实例管理任何急需,那么您只怕不期待这些时间依旧被增大着还要再一次奉行一次。

  在.NET效率中另三个异步方式设计IAsyncResult接口。此中三个例证便是DNS查找主机名的IP地址,BeginGetHoseAddress。这种陈设须要多个措施,二个是伊始实践的BeginMethodName,另二个是试行截止EndMethodName,即你的回调方法。

private void LookupHostName()
{
object unrelatedObject = "hello";
Dns.BeginGetHostAddresses("oreilly.com", OnHostNameResolved, unrelatedObject);
}
private void OnHostNameResolved(IAsyncResult ar)
{
object unrelatedObject = ar.AsyncState;
IPAddress[] addresses = Dns.EndGetHostAddresses(ar);
// Do something with addresses
...
}

  起码这种艺术不会受到残余注册事件的震慑,不过那也异常的对API扩充了复杂。有五个措施并非三个,笔者以为特不自然。

  那二种异步形式都急需你分为四个章程来书写。IAsyncResult形式要你从第2个措施中向第4个措施传递某个参数,就像是自家传递了string类型的"hello"。但是这种办法很复杂,即便你无需以此参数,仍旧只好传递它,况兼反逼你转移为object类型。

 

最简易的异步形式

  能够说下边这段代码具有异步行为,即使不使用async关键字,也不用向方法传递委托:

void GetHostAddress(string hostName, Action<IPAddress> callback)

  小编开采这种方法比其他办法更加的易用。

private void LookupHostName()
{
GetHostAddress("oreilly.com", OnHostNameResolved);
}
private void OnHostNameResolved(IPAddress address)
{
// Do something with address
...
}

  不相同于五个方法的形式,像自家原先提到的,使用异步方法大概用lambda表明式做回调。它兼具主要的好处正是能够在首先个点子中访谈变量。

private void LookupHostName()
{
int aUsefulVariable = 3;
GetHostAddress("oreilly.com", address =>
{
// Do something with address and aUsefulVariable
...
});
}

  那个Lambda有有些难以阅读,况且普通要是你使用多种的异步编制程序,你将索要过Dora姆da表明式互相嵌套,你的代码将会急忙变得犬牙相错和不便管理。

  这种归纳方法的弱点在于他们不再对调用者抛出十一分。在在此之前.NET异步编制程序中,调用EndMethodName只怕得到Result属性时,将会另行抛出极度,所以在代码中大家能够对应的拍卖特别。相反,他们可能在有个别错误位置停下可能根本不去处理。

 

关于Task的介绍

  职责并行实在.NET Framework4.0版本中推出的。其最重大之处是Task类,即意味着多个正在实施的操作。 泛型版本的Task<T>, 当操作完毕时回来类型为T的值。

   在C#5.0 async功用上大家多量的施用了Task,大家将会稍后钻探。不过纵然未有async,你如故得以动用Task,尤其是行使Task<T>来异步编制程序。那样做就可以,你在这里以前三个赶回Task<T>的操作,然后选取ContinueWith方法注册你的回掉方法。

private void LookupHostName()
{
Task<IPAddress[]> ipAddressesPromise = Dns.GetHostAddressesAsync("oreilly.com");
ipAddressesPromise.ContinueWith(_ =>
{
IPAddress[] ipAddresses = ipAddressesPromise.Result;
// Do something with address
...
});
}

  Task的长处就疑似那几个DNS只需求一个办法,使API越发卫生。全数调用异步行为相关的逻辑都可在Task类个中,所以它无需在每八个艺术里都进展复制。那些逻辑能够做过多种中之重的事宜,比如拍卖非常和一块上下文(SynchronizationContexts)。那几个,大家将会在第八章探究,对于在二个特定线程上进行callback很有用途(比方UI线程)。

  最注重的是,Task给大家提供少年老成种采纳异步的相对抽象的操作方式。大家得以应用这种组合型去编写大家的工具,即在超多索要利用Task的图景下提须求大器晚成部分得力的行事。大家将会见到比相当多有关的工具组件(utilities)在第七章当中。

 

手动编写异步代码的标题

   正如我们见到的,大家有多数办法来得以完结异步编程。有生机勃勃部分主意比别的艺术整洁易懂易用,然而也指望您曾经观看他们共有的劣势。你策画写的主次必须要分为五个章程:实际的秘技和回调方法。还恐怕有使用异步方法或嵌套多次lambda表明式作为回调,使您的代码生机勃勃环套风流倜傥环难以明白。

  实际上这里还应该有另二个主题材料。大家曾经说过调用壹次异步方法的景色,不过当您需求多少个异步时会爆发什么样吗?更不佳的是,假设弄供给在循环中调用异步又会发生哪些吧?你为八个主意是利用递归方法,那又比平时的巡回难以阅读多了。

private void LookupHostNames(string[] hostNames)
{
LookUpHostNamesHelper(hostNames, 0);
}

private static void LookUpHostNamesHelper(string[] hostNames, int i)
{
Task<IPAddress[]> ipAddressesPromise = Dns.GetHostAddressesAsync(hostNames[i]);
ipAddressesPromise.ContinueWith(_ =>
{
IPAddress[] ipAddresses = ipAddressesPromise.Result;
// Do something with address
...
if (i + 1 < hostNames.Length)
{
LookUpHostNamesHelper(hostNames, i + 1);
}
});
}

  哇!

  在这里些异步编制程序情势中,引发的另贰个难题正是须求开销多量代码。假设你写一些异步代码,期待在别的地点采纳,你只好提供API,如若API混乱大概忘记那时候的初志无法知道的话,将会渔人之利。异步代码是会“传染”的,因而不但你须要异步API,还影响调用者和调用者的调用者,知道一切程序乱作一团。

 

动用手写异步代码转换示例(第二章结尾三个示范)

  再来谈谈第二章最终二个演示,我们谈谈了多少个会因从网址下载icons,形成UI线程阻塞,并招致现身应用程序未响应的WPF UI app。今后我们将拜候到,将它转形成手写的异步代码。

  第首先要做的正是找到多少个异步API的版本,笔者用(WebClient。下载文件)。正如作者辈曾经见到的,WebClient方法应用基于事件的异步方式(EAP),所以我们得以在开始下载早前注册叁个事件作为回调方法。

private void AddAFavicon(string domain)
{
WebClient webClient = new WebClient();
webClient.DownloadDataCompleted += OnWebClientOnDownloadDataCompleted;
webClient.DownloadDataAsync(new Uri("http://" + domain + "/favicon.ico"));
}
private void OnWebClientOnDownloadDataCompleted(object sender,
DownloadDataCompletedEventArgs args)
{
Image imageControl = MakeImageControl(args.Result);
m_WrapPanel.Children.Add(imageControl);
}

  当然,大家的着实属于一同的逻辑要被分成三个章程。笔者不希罕使用兰姆da来庖代刚才的EAP,因为lambda会并发在真正开头下载前,作者感觉这是不足读的。

  那一个版本的事必躬亲也能够在线(

写在背后

27号入职,花了八天的业余时间,风风雨雨的翻译了第三章。假如您对您有一点点许益处,不要吝啬你的赞,给个激励。不规范和急需补给的地点,也请前辈们多多关照,小编将谦逊改善。下风姿罗曼蒂克章将会介绍 “编写Async方法”

上一篇:【第15期】你知道怎么着成为巨无霸的小磨棚,值得您读书? 下一篇:叫嚣着不愿成为舆论受害者的你,还不是成了舆论凶手