WinForm 异步调用方法
生活随笔
收集整理的這篇文章主要介紹了
WinForm 异步调用方法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
假如要在一個線程中異步執行一個方法,則先創建一個該方法的委托類型,然后CLR會自動為該委托類型定義一個BeginInvoke方法和EndInvoke方法,我們就靠這兩個方法異步調用委托類型指向的方法(這句話有點繞口,呵呵)
BeginInvoke這個方法用于啟動異步調用,該方法具有和要異步執行的方法具有相同的參數列表,只不過又多加了兩個參數,多加的那兩個參數的作用在后面介紹。執行BeginInvoke方法后,將立即返回一個IAsyncResult,用于監視被調用方法執行的進度。
EndInvoke這個方法用于得到異步調用的結果,調用BeginInvoke方法后隨時可以調用EndInvoke方法,假如異步調用還沒有完成,EndInvoke會阻塞到異步調用執行完畢,EndInvoke的參數包括被調用方法的out和ref參數,還有在調用BeginInvoke方法時得到的那個IAsyncResult(好像就是一個哈希表的key,可以靠這個key去得到相應的線程,這樣就可以處理多線程而不至于混亂了)
第一種方法:使用BeginInvoke方法后,主線程去執行一些操作,然后再使用EndInvoke方法等待被調用方法完成,以下是示例代碼
?
using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace sample {class AsyncDemo // 我定義了一個演示的類,里面有一個測試方法TestMethod 其實完全可以把這個TestMethod寫到Main()函數的同一個類中,只不過寫成static方法即可{public string TestMethod(int callDuration, out int threadid){Console.WriteLine("Test Method begins");Thread.Sleep(callDuration);//睡眠callDuration指定的毫秒threadid = AppDomain.GetCurrentThreadId();//獲取當前線程的idreturn "MyCallTime was" + callDuration.ToString();//返回當前線程睡眠的時間}}public delegate string AsyncDelegate(int callDuration, out int threadid); //創建一個AsyncDemo類中TestMethod方法相同簽名的委托類型class Program{static void Main(string[] args){int threadID;AsyncDemo ad = new AsyncDemo();//聲明一個AsyncDemo類型的對象ad,并創建一個實例賦給它AsyncDelegate andl = new AsyncDelegate(ad.TestMethod);//聲明一個AsyncDelegate類型的對象andl,并讓他指向ad對象的TestMethod方法IAsyncResult ar = andl.BeginInvoke(3000, out threadID, null, null);//執行andl的BeginInvoke方法,返回一個IAsyncResult類型的實例對象給ar變量,其實是一個號碼牌(不知道這樣說是否形象)Thread.Sleep(10);//使當前線程睡眠10毫秒(其實可去掉這句,我寫這個的目的是確保異步線程已啟動,再執行以下語句)Console.WriteLine("Main Thread {0} Does Some Work",AppDomain.GetCurrentThreadId());//輸出當前線程的idstring ret = andl.EndInvoke(out threadID, ar);//使用EndInvoke方法,傳入out或ref類型參數和在調用BeginInvoke方法時得到的IAsyncResult,此時主線程將等待異步調用執行完畢,返回結果后執行以下語句Console.WriteLine("The call executed on thread {0},with return value : {1}",threadID, ret);Console.ReadLine();}} }ok,以上是第一種直接使用EndInvoke來等待異步調用完成的方法 ================================================ ================================================第二種方法是借助返回的IAsyncHandle的WaitHandle屬性的WaitOne()方法實現線程同步后,執行代碼,然后將要執行的代碼執行后隨時可調用EndInvoke方法。示例代碼基本沒有什么改動,只是在BeginInvoke方法后執行一個ar.WaitHandle.WaitOne()方法,該方法將阻塞主線程使主線程等待返回ar的begininvoke調用的方法的線程執行完畢(不要怪我說話有點繞,我是說的詳細,否則你弄不明白,仔細看這句話就明白了^o^)。本著一切代碼都是紙老虎的原則,請仔細分析下面的代碼 其實和示例1基本無異 ,只是使用WaitOne()方法同步了一下線程而已using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace sample {class AsyncDemo{public string TestMethod(int callDuration, out int threadid){Console.WriteLine("Test Method begins");Thread.Sleep(callDuration);threadid = AppDomain.GetCurrentThreadId();return "MyCallTime was" + callDuration.ToString();}}public delegate string AsyncDelegate(int callDuration, out int threadid);class Program{static void Main(string[] args){int threadID;AsyncDemo ad = new AsyncDemo();AsyncDelegate andl = new AsyncDelegate(ad.TestMethod);IAsyncResult ar = andl.BeginInvoke(3000, out threadID, null, null);Thread.Sleep(10);Console.WriteLine("Main Thread {0} Does Some Work",AppDomain.GetCurrentThreadId());ar.AsyncWaitHandle.WaitOne();//執行該方法時主線程將等待輔助線程執行完畢,使兩線程同步后再執行以下語句Console.WriteLine("其實很簡單");//執行一些方法string ret = andl.EndInvoke(out threadID, ar);//使用EndInvoke來獲取返回結果和傳入ref和out的變量獲取修改后的實例的位置(這我就不太好用語言來表述了,你自己心領神會吧)Console.WriteLine("The call executed on thread {0},with return value : {1}",threadID, ret);Console.ReadLine();}} }
?
總結
以上是生活随笔為你收集整理的WinForm 异步调用方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 11月份是个少产的季节
- 下一篇: LTE网元间控制面协议