2010-07-12 53 views
0

通常,當我想取消在C#中的BackgroundWorker的,我會做這樣的事情:C#BackgroundWorker的取消與助手功能

 while (backgroundWorker1.IsBusy) 
    { 
     backgroundWorker1.CancelAsync(); 
     autoResetEvent1.WaitOne(BGW_CANCEL_TIMEOUT); 
    } 

在一個應用中有許多backgroundWorkers的。使用輔助函數取消背景工作人員是否有效?

CancelBackgroundWorker(BackgroundWorker bgw, AutoResetEvent are) 
{ 
    while (bgw.IsBusy) 
    { 
     bgw.CancelAsync(); 
     are.WaitOne(BGW_CANCEL_TIMEOUT); 
    } 
} 

我擔心的是,不是將有問題的對象傳遞到函數中,而是進行復制,從而破壞了具有函數的目的。具有該功能的主要目的是減少代碼空間並使應用程序代碼更具可讀性/可維護性。

回答

2

不,這不好。當BGW具有RunWorkerCompleted事件處理程序時,它會導致死鎖。該處理程序只有在主線程閒置並重新進入消息循環時才能運行。在該事件處理程序完成之前,IsBusy屬性將保持爲True。

您在WaitOne調用中有超時,所以至少您的程序不會完全掛起。但是,當WaitOne()返回時,BGW是而不是尚未完成,但RWC事件處理程序尚未運行。唯一可行的選擇是RWC事件處理程序在完成取消操作時執行任何需要的操作。

+0

就是這樣!謝謝! – 2010-07-12 20:09:47

0

您的代碼是錯誤的。

調用CancelAsync僅將BackgroundWorker上的CancellationPending flag設置爲true。預計DowWork事件中的代碼將定期檢查該標誌,並在標誌爲true時停止。

多次調用CancelAsync不會有任何好處,並且應該沒有任何理由凍結UI線程,直到它真正取消。

+0

是的,我意識到這一點。我的backgroundWorker檢查它以查找backgroundWorker1.CancellationPending並相應地退出。我的問題更重要的是backgroundWorker1標誌將由輔助函數設置,還是將設置backgroundWorker副本的標誌,該標誌在函數返回時被銷燬。 – 2010-07-12 14:48:14

+0

由於'BackgroundWorker'類不是一個結構體,所以沒有。所有的C#類總是通過引用傳遞。但是,該功能是無用的。 – SLaks 2010-07-12 14:49:29

+0

除非使用ref或out關鍵字,否則類將按值傳遞。對於參考類型,傳遞參考的副本。 – 2010-07-12 18:47:07