异步编程模型 (APM)

使用 IAsyncResult 设计模式的异步操作被实现为两个方法,分别是 BeginOperationNameEndOperationName,用于开始和结束异步操作 OperationName。 例如,该 FileStream 类提供 BeginReadEndRead 方法,用于从文件中异步读取字节。 这些方法实现方法的 Read 异步版本。

注释

从 .NET Framework 4 开始,任务并行库提供了用于异步和并行编程的新模型。 有关详细信息,请参阅任务并行库(TPL)基于任务的异步模式(TAP)。

调用BeginOperationName后,应用程序可以在调用线程上继续执行指令,同时异步操作将在其他线程上进行。 对于每次调用 BeginOperationName,应用程序还应调用 EndOperationName 以获取作结果。

开始异步操作

该方法 BeginOperationName 开始异步作 OperationName 并返回实现 IAsyncResult 接口的对象。 IAsyncResult 对象存储有关异步作的信息。 下表显示了有关异步操作的信息。

成员 DESCRIPTION
AsyncState 一个可选的特定于应用程序的对象,其中包含有关异步作的信息。
AsyncWaitHandle WaitHandle可用于阻止应用程序执行,直到异步操作完成。
CompletedSynchronously 一个值,该值指示异步操作是否在用于调用 BeginOperationName 的线程上完成,而不是在单独的 ThreadPool 线程上完成。
IsCompleted 一个表示异步操作是否已完成的值。

BeginOperationName 方法接受在方法的同步版本签名中声明的以值或引用方式传递的任何参数。 任何 out 参数都不属于 BeginOperationName 方法签名。 方法 BeginOperationName 签名还包括两个附加参数。 第一个定义了一个 AsyncCallback 委托,该委托引用一个方法,该方法会在异步操作完成时被调用。 如果调用方不希望在作完成时调用方法,则调用方可以指定 nullNothing 在 Visual Basic 中)。 第二个附加参数是用户定义的对象。 此对象可用于将应用程序特定的状态信息传递给异步作完成时调用的方法。 如果一个BeginOperationName方法需要特定于操作的其他参数,例如字节数组来存储从文件中读取的字节,AsyncCallback和应用程序状态对象将作为BeginOperationName方法签名中的最后一个参数。

BeginOperationName 立即返回对调用线程的控制。 如果BeginOperationName方法引发异常,则在启动异步操作之前会引发异常。 BeginOperationName如果方法引发异常,则不调用回调方法。

结束异步操作

EndOperationName方法结束异步操作OperationName。 该方法的 EndOperationName 返回值与其同步对应项返回的类型相同,特定于异步作。 例如,该方法 EndRead 返回从 a FileStream 读取的字节数,该方法 EndGetHostByName 返回一个 IPHostEntry 对象,该对象包含有关主机的信息。 EndOperationName 方法采用该方法同步版本的签名中声明的所有输出参数或引用参数。 除了同步方法中的参数外,该方法 EndOperationName 还包括一个 IAsyncResult 参数。 调用方必须将相应调用返回的实例传递给BeginOperationName

如果 IAsyncResult 对象所代表的异步操作在调用 EndOperationName 时尚未完成,那么 EndOperationName 就会阻止调用线程,直到异步操作完成。 异步操作引发的异常是从 EndOperationName 方法引发的。 未定义多次调用 EndOperationName 同一 IAsyncResult 方法的效果。 同样,也未定义使用 EndOperationName(相关 Begin 方法未返回)调用 IAsyncResult 方法的效果。

注释

对于这两种未定义的情况,实施者应考虑引发 InvalidOperationException

注释

此设计模式的实现者应通过将IsCompleted设置为true、调用异步回调方法(如果有指定)、并发出AsyncWaitHandle信号,通知调用方异步操作已完成。

应用程序开发人员有多个用于访问异步作结果的设计选择。 正确的选择取决于应用程序是否有能在操作完成时执行的指令。 如果应用程序在收到异步操作的结果之前无法执行任何其他工作,则应用程序必须阻塞,直到结果可用为止。 若要阻止,直到异步操作完成,可以使用以下方法之一:

不需要在异步操作完成时进行阻止的应用程序可以使用以下方法之一:

另请参阅