C# 多線程之異步回調
阿新 • • 發佈:2018-05-22
clean leg 多線程 pan ons sync line lee 回調
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);
C# 多線程之異步回調