使用 IAsyncResult 设计模式的异步操作被实现为两个方法,分别是 BeginOperationName
和 EndOperationName
,用于开始和结束异步操作 OperationName。 例如,该 FileStream 类提供 BeginRead 和 EndRead 方法,用于从文件中异步读取字节。 这些方法实现方法的 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 委托,该委托引用一个方法,该方法会在异步操作完成时被调用。 如果调用方不希望在作完成时调用方法,则调用方可以指定 null
(Nothing
在 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信号,通知调用方异步操作已完成。
应用程序开发人员有多个用于访问异步作结果的设计选择。 正确的选择取决于应用程序是否有能在操作完成时执行的指令。 如果应用程序在收到异步操作的结果之前无法执行任何其他工作,则应用程序必须阻塞,直到结果可用为止。 若要阻止,直到异步操作完成,可以使用以下方法之一:
从应用程序的主线程调用
EndOperationName
,阻止应用程序执行,直到作完成。 有关演示此方法的示例,请参阅 通过结束异步作来阻止应用程序执行。使用AsyncWaitHandle以阻止应用程序执行,直到一个或多个操作完成。 有关演示此方法的示例,请参阅 使用 AsyncWaitHandle 阻止应用程序执行。
不需要在异步操作完成时进行阻止的应用程序可以使用以下方法之一:
通过定期检查 IsCompleted 属性,并在操作完成时调用
EndOperationName
,以轮询操作的完成状态。 要查看演示此技术的示例,请参阅 “轮询异步操作的状态”。操作完成时使用AsyncCallback委托来指定一个要调用的方法。 有关演示此方法的示例,请参阅 使用 AsyncCallback 委托结束异步操作。