BegainInvoke 和EndInvoke
1、BegainInvoke 从线程池中获取一个线程,并且让引用方法在新的线程中运行。
2、BegainInvoke 返回给调用线程一个IAsyncResult接口的对象的引用。这个接口引用包含了在线程池中运行的异步方法的当前状态,原始线程然后可以继续运行。
3、EndInvoke 方法用来获取有异步方法调用返回的值。并且释放线程所用的资源。
EndInvoke 有以下的特性。
接受一个由BegainInvoke方法返回的IAsyncResult对象的引用,并找到它关联的线程。
如果线程池里面的线程退出了,会做以下的事情。
清理退出的线程的状态并释放其资源。
找到引用方法的返回值并作为其返回值
如果调用的线程池里面的线程还在运行,调用线程就会停止并等待。直到清理完毕并由返回值。
EndInvoke 是为开启的线程进行清理。所以确保每一个BegainInvoke 都会调用EndInvoke。
如果EndInvoke 出现异常。则会抛出异常。
异步编程模式有三种模式
(1)等待到一直结束
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | delegate long Mysum( int frist, int second); class Program { static void Main( string [] args) { Mysum mysum = new Mysum(Sum); Console.WriteLine( "Before BegainInvoke" ); IAsyncResult iar = mysum.BeginInvoke(3, 5, null , null ); //开始异步调用 Console.WriteLine( "After BegainInvoke" ); Console.WriteLine( "Doing Stuff" ); long Result = mysum.EndInvoke(iar); //等待结束并返回结果。 Console.WriteLine( "After EndInvoke:{0}" , Result); Console.ReadLine(); } static long Sum( int x, int y) { Console.WriteLine( " inside sum" ); Thread.Sleep(10000); return x + y; } } /// /// 异步委托的循环模式 /// /// static void Main( string [] args) { Mysum mysum = new Mysum(Sum); Console.WriteLine( "Before BegainInvoke" ); IAsyncResult iar = mysum.BeginInvoke(3, 5, null , null ); //开始异步调用 Console.WriteLine( "After BegainInvoke" ); while (!iar.IsCompleted) { Console.WriteLine( "Not Done" ); for ( int i = 0; i < 1000000; i++) { Console.WriteLine($ "{i}" ); if (iar.IsCompleted) { break ; } } } Console.WriteLine( "Done" ); long Result = mysum.EndInvoke(iar); //等待结束并返回结果。 Console.WriteLine( "After EndInvoke:{0}" , Result); Console.ReadLine(); } static long Sum( int x, int y) { Console.WriteLine( " inside sum" ); Thread.Sleep(100); return x + y; } //回调函数 static void CallWhenDone(IAsyncResult iar) { Console.WriteLine( " inside CallWhenDone" ); AsyncResult ar = (AsyncResult)iar; //显示转换为AsyncResult类。 Mysum sums=(Mysum)ar.AsyncDelegate; //返回一个指向被调用来开启异步方法的委托的引用 long result = sums.EndInvoke(iar); Console.WriteLine( " The result is {0}" , result); } //委托方法 static long Sum( int x, int y) { Console.WriteLine( " inside sum" ); Thread.Sleep(100); return x + y; } //回调函数 static void CallWhenDone(IAsyncResult iar) { Console.WriteLine( " inside CallWhenDone" ); AsyncResult ar = (AsyncResult)iar; //显示转换为AsyncResult类。 Mysum sums=(Mysum)ar.AsyncDelegate; //返回一个指向被调用来开启异步方法的委托的引用 long result = sums.EndInvoke(iar); Console.WriteLine( " The result is {0}" , result); } //委托方法 static long Sum( int x, int y) { Console.WriteLine( " inside sum" ); Thread.Sleep(100); return x + y; } |
IAsyncResult 接口被AsyncResult对象包含,AsyncResult类表现为异步的状态。
BegainInvoke 方法调用时时,系统会创建一个AsyncResult 对象。不会返回类对象的引用,而是返回对象中包含IAsyncResult接口的引用。
AsyncResult 对象包含Asyncdelegate属性,它返回一个指向被调用来开启异步方法的委托的引用。这个属性时类的一部分,不是接口的一部分。
IsCompleted 属性返回一个布尔值,表示异步是否完成。
AsyncState属性返回一个对象的引用。作为BegainInvoke方法调用时State的参数。返回是一个Object类型的引用。
2、循环模式
循环模式在判断IAsyncResult中的IsCompleted 是否为True,如果一直为false,则处理循环内的事情,如果TRUE 则返回主线程中去。
代码如下
3、回调模式,回调模式不回阻塞线程。而一直等待模式,循环模式,也会存在阻塞线程,而回调模式不存在阻塞线程。BegainInvoke 开始异步线程后,立即返回主线程,结果由回调函数处理。
理论
回调方法的签名和返回参数必须跟AsyncCallback 委托类型所描述的一致。它需要方法接受一个IAsyncResult 作为参数,并且返回参数为Void
案例如下
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异