C# 多线程之异步回调
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Remoting.Messaging; using System.Text; using System.Threading; namespace yibu { public delegate int AddHandler(int a,int b); public class CAdd { public static int Add(int a, int b) { Console.WriteLine("开始计算..."); Console.WriteLine("当前线程ID:" + Thread.CurrentThread.ManagedThreadId); Thread.Sleep(4000); Console.WriteLine("计算完成"); return a + b; } } class Program { void cleanup(int result) { Console.WriteLine("调用者继续工作"); Console.WriteLine(result); Console.ReadKey(); } static void sync_call() { Console.WriteLine("Sync_call_test"); AddHandler handler = new AddHandler(CAdd.Add); int result = handler.Invoke(1, 2); Console.WriteLine("调用者继续工作"); Console.WriteLine(result); Console.ReadKey(); } static void async_call() { Console.WriteLine("Async_call_test"); AddHandler handler = new AddHandler(CAdd.Add); IAsyncResult result = handler.BeginInvoke(1, 2, null, null); Console.WriteLine("调用者继续工作"); Console.WriteLine(handler.EndInvoke(result)); Console.ReadKey(); } static void async_callback() { Console.WriteLine("Async_callback_test"); AddHandler handler = new AddHandler(CAdd.Add); IAsyncResult result = handler.BeginInvoke(1, 2, new AsyncCallback(mycall), "AsyncState:OK"); Console.WriteLine("调用者继续工作"); //Console.ReadKey(); } static void Main() { Console.WriteLine("主线程ID:" + Thread.CurrentThread.ManagedThreadId); async_callback(); Console.WriteLine("happy coding,yes"); Thread.Sleep(44000); Console.WriteLine("Continue Happy coding"); Thread.Sleep(2000); Console.ReadKey(); } static void mycall(IAsyncResult result) { Console.WriteLine("where am i?"); Console.WriteLine("当前线程ID:" + Thread.CurrentThread.ManagedThreadId); AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate; Console.WriteLine(handler.EndInvoke(result)); Console.WriteLine(result.AsyncState); } } }
代码中主函数使用的是异步回调,为了说明其优越性,代码提供了
其他两种方法来做比较:
1.同步调用,代码在sync_call函数中,
这个其实还是本线程调用,和调用个函数没区别。
2.异步调用
在async_call函数中,调用完handler.BeginInvoke 之后,主线程会继续往下执行,
但是在handler.EndInvoke的时候,如果任务没有完成,还是会阻塞在这里。
注意使用异步回调的核心代码:
IAsyncResult result = handler.BeginInvoke(1, 2, new AsyncCallback(mycall), "AsyncState:OK");
第三个参数注册回调函数,第三个传递一个object对象。
回调函数mycall在任务线程里面执行,
AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate;来获取委托对象,然后再
handler.EndInvoke(result) 返回值。
在回调函数中获取主线程的委托对象还可以使用如下方法:
在BeginInvoke的时候将 ,委托对象传到第四个参数,
回调函数中使用result.AsynState 再转成(AddHandler)
AddHandler handler = (AddHandler)(result.AsyncState);