使用 IAsyncResult 进行 .NET 异步编程
微软早在.net2.0, 也就是VS2005的时候,就提供了一整套的异步编程设计模式,有3中常用的方式:
1. 使用 IAsyncResult 调用异步方法
2. 使用委托进行异步编程
3. 使用事件进行异步多线程编程
注: IAsyncResult 方式通常是用委托来实现的。所以可以认为前面2种方式就是一种。
http://msdn.microsoft.com/zh-cn/library/2e08f6yc.aspx
使用 IAsyncResult 调用异步方法
1. 有两个配对的方法,BeginXXX() 和 EndXXX()。它们是XXX()方法的异步执行。
BegingXXX()的参数是在XXX()的参数基础上增加 AsyncCallback 和 AsyncState。
EndXXX()的返回值和XXX()的返回值是一样的。
例如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public delegate string AsyncMethodCaller(( object param1, object param2); public class AsyncDemo { private AsyncMethodCaller _asyncDelegate = new AsyncMethodCaller(Run); public IAsyncResult BeginRun( object param1, object param2, AsyncCallback asyncCallBack, Object asyncState) { asyncDelegate.BeginInvoke(param1, param2, callBack, stateObject); } public object EndRun(IAsyncResult asyncResult) { m_asyncDelegate.EndInvoke(asyncResult); } Public object Run( object param1, object param2); } |
1 | |
2. IAsyncResult 对象中存储有关异步操作的信息。
3. 阻止应用程序执行的几种方法
a. 通过结束异步操作来阻止应用程序执行
就是EndXXX() 调用时,如果 IAsyncResult 对象表示异步操作未完成,则调用线程会被阻止,就是说它之后的逻辑的会被阻止。
1 2 3 4 5 6 7 | IAsyncResult result = AsyncDemo.BeginRun(param1, param2, null , null ); AsyncDemo.EndRun(result); // when Run() method is completed. Continue to go. ContinueToGo(); |
b. 使用 AsyncWaitHandle 阻止应用程序的执行。
在BeingXXX()之后调用 IAsyncResult.AsyncWAitHandle 中的相应方法也可以阻止调用线程。例如
1 2 3 4 5 | IAsyncResult result = AsyncDemo.BeginRun(param1, param2, null , null ); // Wait until the operation completes. result.AsyncWaitHandle.WaitOne(); |
c. 轮询异步操作的状态。
在BeingXXX()之后调轮询IAsyncResult.IsCompleted属性来确定此操作是否已完成
1 2 3 4 5 6 7 8 9 10 11 12 | IAsyncResult result = AsyncDemo.BeginRun(param1, param2, null , null ); While(result.IsCompleted != true ) { // Waiting until IsCompleted is true. } // when Run() method is completed. Continue to go. ContinueToGo(); |
1 | |
d. 使用 AsyncCallback 委托结束异步操作。
就是在代理里面根据具体情况调用Endxxx()方法来让调用线程继续运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Public void MainFunc() { AsyncCallback callBack = new AsyncCallback(ProcessRun); IAsyncResult result = AsyncDemo.BeginRun(param1, param2, callBack, null ); ContinueToGo(); } Public void ProcessRun(IAsyncResult result) { AsyncDemo.EndRun(result); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理