在.NET多線程程序中使用異步調(diào)用的簡易方法
原創(chuàng)【51CTO獨(dú)家特稿】簡介
對于開發(fā)者來說,運(yùn)行異步任務(wù)簡直就是一場惡夢,特別是初學(xué)者更是如此。在本文附帶的代碼中,您將發(fā)現(xiàn)一個簡單的AsyncWorker類,它能夠使您輕松完成異步任務(wù)的處理,即使您對異步調(diào)用沒有全面深入的了解。當(dāng)然,我們也很希望看到您貢獻(xiàn)的代碼,尤其是對于ReportProgress函數(shù),因?yàn)樗€未經(jīng)測試。
背景知識
我為什么編寫這個助手類(helper class)呢? 簡單地說,這是因?yàn)槲也幌矚g.NET BackgroundWorker類,以及所有與IsBusy參數(shù)有關(guān)的問題。有時候,即使您成功地終止了異步任務(wù),IsBusy也不會從true變?yōu)閒alse。類backgroundWorker會強(qiáng)迫您在while循環(huán)中使用Application.DoEvents。也許還有其它正確使用它的方法,但是我至今還沒找到。我嘗試按照backgroundWorker的設(shè)計方法建立一個盡可能簡單的替換物。
代碼用法
如果您看過BackgroundWorker的文檔,那么使用下面的代碼也應(yīng)該不成問題。為了初始化AsyncWorker,我們做如下定義:
AsyncCallback m_asyncWorker;
然后,在您的代碼(構(gòu)造函數(shù))中對其進(jìn)行初始化,如下所示:
- //通過設(shè)置maximumCount,我們可以對簡單的ThreadPool進(jìn)行摹擬。
- //參數(shù)maximumCount用于指出可以同時啟動多少個并行的線程。如果abortIfBusyParameter被設(shè)為true,那么其他線程就只能等待,或者被拒絕。
- this.m_asyncWorker = new AsyncWorker(1);
- //分配一個后臺任務(wù)
- this.m_asyncWorker.DoWork += new DoWorkEventHandler(m_asyncWorker_DoWork);
您的后臺任務(wù)可以是任何您喜歡的東西:
- void m_asyncWorker_DoWork(object sender, DoWorkEventArgs e) {
- Console.WriteLine("Hello world! I was started asynchronously.");
- }
最后調(diào)用background worker :
- //因?yàn)閍bortIfBusyParameter 被設(shè)置為true,所以如果前面的調(diào)用仍然在運(yùn)行的話,RunWorkerAsync將返回false(中止調(diào)用)。
- if (!this.m_asyncWorker.RunWorkerAsync(true)) {
- Console.WriteLine("Worker in use....");
- }
通過把RunWorkerAsync參數(shù)abortIfBusy設(shè)置為true,即使前面的異步調(diào)用仍在運(yùn)行,您也可以跳過這個事件。通過將其設(shè)為false,它會進(jìn)入一個等待隊列,并在IsBusy從true轉(zhuǎn)換為false的時候馬上觸發(fā)。 這個機(jī)制對于性能敏感的應(yīng)用程序來說非常有用。如果您有許多啟動異步調(diào)用的“低優(yōu)先級”事件,并且如果前面的異步調(diào)用仍在運(yùn)行(IsBusy),那么您可以決定是否應(yīng)該啟動另一個異步調(diào)用。
例如:如果您在屏幕上拖動一個對象的時候,那么就無需每次都重繪它。只有當(dāng)IsBusy為false的時候才需對其進(jìn)行繪制。 如果您想要獲得平滑效果,只需增加maximumCount(您的線程池)即可。
最后,如果您需要一個回調(diào)函數(shù),那么您可以自己預(yù)訂RunWorkerCompleted事件。
- //分配RunWorkerCompleted。它是您的回調(diào)函數(shù)事件。
- this.m_asyncWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_asyncWorker_RunWorkerCompleted);
結(jié)束語
希望這個工具可以使您的生活變得更加輕松。請不要詢問JustDoSomething類的鎖定問題,因?yàn)樗瞧渌鼫y試的一部分。
【編輯推薦】