2014-11-20 96 views
2

我有一個我已經設置好的後臺工作器,我想在完成後重新啓動它。也就是說,在DoWork()完成後,如果結果不成功,我想再次從RunWorkerCompleted()處理程序中調用RunWorkerAsync()。當我在RunWorkerCompleted()中時,能否確定IsBusy = false?我可以在BackgroundWorker的RunWorkerCompleted()中調用RunWorkerAsync()嗎?

例如:

void myThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if ((e.Error == null) && !e.Cancelled && (bool)e.Result) 
     // do stuff 
    else 
     myThread.RunWorkerAsync(); 
} 

我似乎無法找到任何地方的這種行爲確認。

+1

Hans Passant在這裏的答案(https://social.msdn.microsoft.com/Forums/vstudio/en-US/ad9a9a02-8a11-4bb8-b50a-613bcaa46886/backgroundworkerisbusy-question)是相當不錯的確認。 – 2014-11-20 20:03:41

+0

有趣。它是有道理的,但你不想在後臺線程上改變一個潛在的UI綁定屬性。 – 2014-11-20 20:10:45

+0

沒錯。儘管從這裏引用的文檔(http://stackoverflow.com/a/2806824/304620)看來,RunWorkerCompleted()將在UI線程上被調用,從而允許在其中進行這種操作。我只是不清楚IsBusy是否已被設置爲false,或者在RunWorkerCompleted()完成之前可能保持爲true。 – 2014-11-20 20:24:44

回答

1

不幸的是,文件不明確的問題。最重要的是,IsBusy屬性的代碼示例實際上非常糟糕,因爲它在屬性上自旋等待,並在循環中調用Application.DoEvents()

也就是說,正如其他人所建議的那樣,最明智的設計是僅當異步工作人員實際運行時標誌爲true。即當DoWork事件處理程序返回時,它應該被設置回false。而事實上,如果我們看一下the implementation,人們看到這樣的:

private void AsyncOperationCompleted(object arg) 
{ 
    isRunning = false; 
    cancellationPending = false; 
    OnRunWorkerCompleted((RunWorkerCompletedEventArgs)arg); 
} 

public bool IsBusy 
{ 
    get 
    { 
     return isRunning; 
    } 
} 

這裏的isRunning標誌是什麼IsBusy財產收益,這是什麼RunWorkerAsync()檢查,看有無異常應該被拋出。從這裏可以看出,在提出RunWorkerCompleted事件之前,實現將它重新設置爲false

所以,是的…從RunWorkerCompleted事件處理程序中調用RunWorkerAsync()是絕對安全的。

如果沒有記錄下來,實現可能會發生變化的遠程可能性。但在現階段,如果發生這種情況,我會非常驚訝。特別是在代碼是開源的情況下,實現和其他任何事情一樣成爲行爲規範。

+0

優秀的答案。感謝您的來源鏈接。我沒有意識到這是可用的! – 2014-11-21 04:49:18

1

我看不出有什麼理由不能。按照定義它已經完成了,所以IsBusy應該總是假的。你回到你所屬的UI線程上。

相關問題