Asynchronous Programming Model (APM)异步编程模型

https://msdn.microsoft.com/zh-cn/library/ms228963(v=vs.110).aspx

一、概念

An asynchronous operation that uses the IAsyncResult design pattern is implemented as two methods named BeginOperationName and EndOperationName that begin and end the asynchronous operation OperationName respectively.

For example, the FileStream class provides the BeginRead and EndRead methods to asynchronously read bytes from a file.

These methods implement the asynchronous version of the Read method.

After calling BeginOperationName, an application can continue executing instructions on the calling thread while the asynchronous operation takes place on a different thread.

For each call to BeginOperationName, the application should also call EndOperationName to get the results of the operation.

 

二、Beginning an Asynchronous Operation开始异步操作

The BeginOperationName method begins asynchronous operation OperationName and returns an object that implements the IAsyncResult interface.

IAsyncResult objects store information about an asynchronous operation. 

The following table shows information about an asynchronous operation.

 

第一个属性,AsyncState,An optional application-specific object that contains information about the asynchronous operation.

第二个属性,AsyncWaitHandle ,A WaitHandle that can be used to block application execution until the asynchronous operation completes.

第三个属性,CompletedSynchronously , A value that indicates whether the asynchronous operation completed on the thread used to call BeginOperationName instead of completing on a separateThreadPool thread.

第四个属性,IsCompleted ,A value that indicates whether the asynchronous operation has completed.

 

A BeginOperationName method takes any parameters declared in the signature of the synchronous version of the method that are passed by value or by reference.

Any out parameters are not part of the BeginOperationName method signature.

The BeginOperationName method signature also includes two additional parameters.

The first of these defines an AsyncCallback delegate that references a method that is called when the asynchronous operation completes.

The caller can specify null (Nothing in Visual Basic) if it does not want a method invoked when the operation completes.

The second additional parameter is a user-defined object.

This object can be used to pass application-specific state information to the method invoked when the asynchronous operation completes.

 

If a BeginOperationName method takes additional operation-specific parameters, such as a byte array to store bytes read from a file, the AsyncCallback and application state object are the last parameters in the BeginOperationName method signature.

 public override IAsyncResult BeginRead(byte[] array, int offset, int numBytes, AsyncCallback userCallback, object stateObject);
 public static IAsyncResult BeginGetHostByName(string hostName, AsyncCallback requestCallback, object stateObject);


Begin OperationName returns control to the calling thread immediately.

If the BeginOperationName method throws exceptions, the exceptions are thrown before the asynchronous operation is started.

If the BeginOperationName method throws exceptions, the callback method is not invoked.

 

三、Ending an Asynchronous Operation结束异步操作

The EndOperationName method ends asynchronous operation OperationName.

The return value of the EndOperationName method is the same type returned by its synchronous counterpart and is specific to the asynchronous operation.

For example, the EndRead method returns the number of bytes read from a FileStream and the EndGetHostByName method returns an IPHostEntry object that contains information about a host computer.

 public class FileStream : Stream
{
    public override int Read(byte[] array, int offset, int count);
    public override int EndRead(IAsyncResult asyncResult);
}
public static class Dns
{
    public static IPHostEntry GetHostByName(string hostName);
    public static IPHostEntry EndGetHostByName(IAsyncResult asyncResult);
}

 

The EndOperationName method takes any out or ref parameters declared in the signature of the synchronous version of the method.

In addition to the parameters from the synchronous method, the EndOperationName method also includes an IAsyncResult parameter.

Callers must pass the instance returned by the corresponding call to BeginOperationName.

 

If the asynchronous operation represented by the IAsyncResult object has not completed when EndOperationName is called, EndOperationName blocks the calling thread until the asynchronous operation is complete.

Exceptions thrown by the asynchronous operation are thrown from the EndOperationName method.

The effect of calling the EndOperationName method multiple times with the same IAsyncResult is not defined.

Likewise, calling the EndOperationName method with an IAsyncResult that was not returned by the related Begin method is also not defined.

Note:

For either of the undefined scenarios, implementers should consider throwing InvalidOperationException.

 

Note:

Implementers of this design pattern should notify the caller that the asynchronous operation completed by setting IsCompleted to true, calling the asynchronous callback method (if one was specified) and signaling the AsyncWaitHandle.

 

Application developers have several design choices for accessing the results of the asynchronous operation.

The correct choice depends on whether the application has instructions that can execute while the operation completes.

If an application cannot perform any additional work until it receives the results of the asynchronous operation, the application must block until the results are available.

To block until an asynchronous operation completes, you can use one of the following approaches:

第一种方法

Call EndOperationName from the application’s main thread, blocking application execution until the operation is complete.

第二种方法

Use the AsyncWaitHandle to block application execution until one or more operations are complete.

 

Applications that do not need to block while the asynchronous operation completes can use one of the following approaches:

Poll for operation completion status by checking the IsCompleted property periodically and calling EndOperationName when the operation is complete. 

 

Use an AsyncCallback delegate to specify a method to be invoked when the operation is complete. 

 

 

 

==总结==2015年10月08日更新==

很早之前就在纸上写了,一直懒,现在才更新

1.BeginRead和EndRead,是Read的异步版本,调用BeginRead之后,程序还会继续往下执行,异步操作是在一个不同的线程上处理的。

每一次调用BeginRead,都要调用一次EndRead来获取操作结果。

 

2.BeginRead返回的对象实现了IAsyncResult接口

BeginRead的参数,除了和同步版本一样的参数外(不附带out参数),还有2个额外的参数

多出来的参数1:AsyncCallback委托,指定了在异步操作结束后,需要调用的方法

多出来的参数2:用户自定义的一个Object,可以用来传递应用程序的状态信息

这2个多出来的参数放在BeginRead的参数列表的最后

 异常处理

如果BeginRead触发异常的话,那么异常会在异步操作开始之前被抛出,并且回调方法不会触发

 

3.EndRead的返回值的类型,和同步方法的返回值的类型是一样的

EndRead的参数,会附带同步方法中的out以及ref参数

调用者需要把BeginRead的返回对象(实现了IAsyncResult接口的对象),作为EndRead的参数

 

如果EndRead方法在调用的时候,IAsyncResult对象的所代表的对象的操作尚未完成,那么调用EndRead的线程就会一直阻塞,直到异步操作完成

异常处理

异步操作导致的异常,会在EndRead操作抛出

 

有2种方法来处理操作结果(不同的情况处理方式不同)

1.如果应用程序的下一步操作依赖于返回结果

(1)主线程调用EndRead方法,在异步操作完成之前阻塞主线程

(2)使用AsyncWaitHandle阻塞主线程

 

2.如果应用程序的下一步操作不依赖返回结果

(1)轮询IsCompleted属性,等到完成时再调用EndRead

(2)使用AsyncCallback指定回调方法

posted @ 2014-11-09 19:59  ChuckLu  阅读(413)  评论(0编辑  收藏  举报