异步委托
异步委托提供以异步方式调用同步方法的能力。
当同步调用委托时,Invoke()方法直接对当前线程调用目标方法;
当异步调用委托时,CLR将对请求进行排队并立即返回到调用方,将对来自线程池的线程调用该目标方法,提交请求的原始线程继续与目标方法并行执行,该目标方法是对线程池线程运行的.
1)、BeginInvoke()方法
BeginInvoke()方法启动异步调用,它与需要异步执行的方法具有相同的参数。
另外,还有两个可选参数:第一个参数是AsyncCallback委托,该委托引用在异步调用完成时要调用的方法;第二个参数是用户定义的对象,该对象可向回调方法传递信息;
BeginInvoke立即返回,不等待异步调用完成;
BeginInvoke返回IAsyncResult,这个结果可用于监视异步调用的进度;
2)、EndInvoke()方法
EndInvoke()方法检索异步调用的结果;
在调用BeginInvoke()方法后,可以随时调用EndInvoke()方法,如果异步调用尚未完成,则EndInvoke()方法将一直阻止调用线程,直到异步调用完成后才允许调用线程执行;
EndInvoke()的参数需要异步执行的方法的out和ref参数以及由BeginInvoke()返回的IAsyncResult。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Runtime.Remoting.Messaging; namespace ConsoleApplication { public delegate string DeleMethod(string name); class Program { static void Main(string[] args) { DeleMethod delemethod = Speaking; //执行异步委托 IAsyncResult result = delemethod.BeginInvoke("Mr.w", null, null); Console.WriteLine("异步调用开始:"); string s = delemethod.EndInvoke(result); //主线程方法 Console.WriteLine("异步调用结果:"+s); //阻止主线程退出程序 Console.ReadKey(); } //要被委托调用的方法 static string Speaking(string name) { //利用休眠3秒钟,模拟委托执行的方法很长 Thread.Sleep(TimeSpan.FromSeconds(3)); Console.WriteLine("我的名字是:{0}", name); return "委托方法执行完毕!"; } } }
如果不调用EndInvoke,线程池中生成的线程默认的是后台线程,如果没有Console.ReadLine(),原始线程(前台线程)关闭的时候,后台线程也会关闭。
如果调用EndInvoke,没有Console.ReadLine(),异步调用没有完成,原始线程会一直阻塞,直到异步线程调用完成。
异步回调
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Runtime.Remoting.Messaging; namespace ConsoleApplication { public delegate string DeleMethod(string name); class Program { static void Main(string[] args) { DeleMethod delemethod = Speaking; //声明回调函数 AsyncCallback callback = new AsyncCallback(CallBack); //执行异步委托 delemethod.BeginInvoke("Mr.w", callback, null); Console.WriteLine("当前线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString()); //主线程方法 Console.WriteLine("下面我还要执行方法...."); //阻止主线程退出程序 Console.ReadKey(); } //回调方法 static void CallBack(IAsyncResult ar) { Console.WriteLine("当前线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString()); AsyncResult result = (AsyncResult)ar; DeleMethod delemethod = (DeleMethod)result.AsyncDelegate;//通过AsyncResult的AsyncDelegate获得delemethod委托对象 string s = delemethod.EndInvoke(ar); Console.WriteLine(s); Console.WriteLine("当前线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString()); } //要被委托调用的方法 static string Speaking(string name) { //利用休眠3秒钟,模拟委托执行的方法很长 Thread.Sleep(TimeSpan.FromSeconds(3)); Console.WriteLine("当前线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString()); Console.WriteLine("我的名字是:{0}", name); return "委托方法执行完毕!"; } } }
这里可以看出,如果没有Console.ReadLine(),原始线程也不会被阻塞。
http://www.cnblogs.com/IAmBetter/archive/2012/02/13/2348912.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)