《.NET4.0 面向对象编程漫谈》读书笔记 ——第10章 异步编程模式

http://www.cnblogs.com/laosu/archive/2011/05/23/2054491.html

 

10章 异步编程模式

【摘要】:异步编程充分利用多线程技术带来的好处,而不需要程序员了解多线程开发中的复杂细节。本章讲述了基于IAsyncResult的异步模式、基于事件的异步模式。



第1节   
程序的同步执行和异步执行


1、同步概念:
若在代码中调用了一个方法,需要等待此方法所有的代码执行完毕之后,才能回到原来的地方执行下一行代码,这种程序运行方式称为同步。


2、异步概念:


   在调用方法之后,不用等待方法执行完成就马上执行下一条语句,这种程序运行方式称为异步。


3、异步调用的本质:不在主线程中执行,而在另一辅助线程中与主线程并行执行。


 


第2节  
基于委托的异步编程模式


1、  当定义一个委托时,编译器会生成如下的类,借助委托的BeginInvoke和EndInvoke方法实现异步调用。


Public sealed class CalculateFolderSizeDelegate:MulticastDelegate


{


       Public CalculateFolderSizeDelegate(object target,int methodPtr)


        { ……}


       Public virtual <方法返回值类型> Invoke (<输入和输出参数>)


        { ……}


       Public virtual IAsyncResult BeginInvoke(<输入和输出变量>,AsyncCallback
callback,object asyncState)


       { ……}


       Public virtual <方法返回值类型>
EndInvoke(<声明为ref或out的参数>,IAsyncResult result)


       { ……}


A、 
BeginInvoke的第一个参数为方法签名中的参数列表,第二个参数callback是当异步调用结束时自动回调的方法,第三个参数asyncState用于向第二个参数所确定的callback回调方法提供额外的信息。


B、  BeginInvoke方法返回一个IAsyncResult接口的对象。


Public interface IAsyncResult


{


  Object AsyncState {get;}


  WaitHandle AsyncWaitHandle { get;}


  Bool CompletedSynchronously {get;}


  Bool IsCompleted {get;}



C、 
EndInvoke:发现异步调用完成时,它取出此异步调用方法执行的结果作为其返回值,如果异步调用方法有声明为ref和out的参数,它也负责填充它。


 


第3节 基于委托的异步编程模式的实践


1、  当异步调用完成之时,调用者线程如何知道调用的执行情况。


        A、  使用轮询  如通过IAsyncResult对象的IsCompleted或AsyncWaitHandle实现。


        B、  异步回调。


2、  处理异常调用中的异常。


       需在EndInvoke方法所在的代码处捕获异步调用抛出的异常。


3、实现异步调用任务的同步问题。


4
实现IAsyncResult异步调用模式的组件


1、  在.NET基类型库中,有一些现有的组件直接实现了IAsyncResult异步调步模式,这些组件通常同时提供某个方法的同步与异步调用形式。


以WebRequest 为例。


IAsyncResult BeginGetResponse(AsyncCallback callback, object
state)  //异步


IAsyncResult BeginGetRequestStream(AsyncCallback callback, object
state) //异步


Stream EndGetRequestStream(IAsyncResult asyncResult)


WebResponse EndGetResponse(IAsyncResult asyncResult)


Stream GetRequestStream()  //同步


WebResponse GetResponse()  //同步


2、  方法有如下特点:
      A、凡有一个BeginXXX的,一定有一个“EndXXX”方法相对应。
     

B、每组“BeginXXX/EndXXX”,一定有一个对应的“XXX”同步方法。
     
C、“EndXXX”方法与对应的同步方法“XXX”的返回值类型相同。
     
D、“BeginXXX”返回一个IAsyncResult对象,而“EndXXX”方法的参数接收此对象。


3、此模式前基于委托的异步调用模式几乎一模一样,因此前面介绍的编程技巧可以继续使用。


 


第5节 基于事件的异步调用模式


1、  在.NET基类库中有部分组件实现了另一种异步模式,这就是基于事件的异步模式(Event-based Asynchronous
Pattern),简称为EAP。


以WebClient 为例。


public void DownloadFileAsync(Uri  address, string fileName);


public void DownloadFileAsync(Uri  address, string fileName,object
userToken);


public void CancelAsync();  //取消任务


2、  EAP有如下特点:


      A、 实现了EAP的组件定义了以“Async”结尾的异步调用方法。
      B、
当异步调用任务结束时,会激发一个相应的事件,事件的参数包含重要的信息。
           如
WebClient会激发DownloadFileCompleted事件,参数信息存在 AsyncCompletedEventArgs对象中。
     
C、 实现了EAP的组件可能会提供一个用于取消异步任务的方法。
      D、实现了EAP的组件提供一个向用户报告进度的事件。
         
如WebClient的 DownloadProgressChanged 事件。


3、【感】:用EAP组件原来是这么简单。


 


6
异步编程小结


1、  分类:异步编程分为 基于IAsyncResult的异步模式和基于事件的异步模式。而前者又分为基于委托的异步调用与使用类基类库中的组件两种。


2、  异步调用的每个方法都是独立的线程中执行的,其本质上就是一种多线程程序。


3、  适合场景:
      A、 直接使用基类库中拥有异步调用特性的组件,如WebClient。
      B、
需要在后台运行一些较耗费时间的任务,这些任务彼此相互独立,而且没有代码直接访问可视化的控件。


4、 不适合场景:
      当在后台完成的工作有复杂的同步关系,或者必须访问共享的资源,不适合采用异步编程方法,而应直接应用多线程技 
术或任务并行库来开发。

你可能感兴趣的:(.net)