2011-09-15 156 views
0

我有一個簡單的BackgroundWorker定義,它使用閉包爲它的DoWork和RunWorkerCompleted事件處理程序,分別設置和檢查布爾值。在簡化的形式中,該代碼(在.NET 3.5 C#)看起來像這樣:閉包和BackgroundWorker事件處理程序

public void SomeMethod() 
    { 
     BackgroundWorker worker = new BackgroundWorker(); 

     bool result = false; 
     worker.DoWork += new DoWorkEventHandler(
      (sender, e) => 
      { 
       result = LengthyOperation(); 
      }); 

     worker.RunWorkerCompleted +=new RunWorkerCompletedEventHandler(
      (sender, e) => 
      { 
       AppendRunLog("Result: " + (result ? "PASS" : "FAIL")); 
      }); 

     worker.RunWorkerAsync(); 
    } 

的someMethod從主UI線程上的WPF按鈕處理程序調用。

通常這很好,但每隔一段時間我都會得到一個報告,說明應該傳遞的操作失敗(根據LongyOperation內部生成的日誌),即布爾結果在完成處理程序中記錄爲false時該操作應該在DoWork處理程序中返回true。

我搜索並測試了LongyOperation中的代碼,確保內部沒有一些細微的錯誤,我相當確信它很乾淨。我無法在我的開發環境中重現它。

我在設置和讀取結果值的過程中是否存在競爭條件?我期望在完成事件被觸發之前,分配操作將在DoWork中完成。

回答

0

對我來說應該沒問題,假設BackgroundWorker基礎結構確保存在適當的內存障礙。

您確定您不只有兩個併發操作,並且您同時看到兩組日誌?

+0

在簡化示例中,我忽略了禁用按鈕的部分,以便在操作完成之前無法再次觸發操作。日誌與此一致。我有一個項目將其轉換爲.NET 4,我可能會將BackgroundWorkers轉換爲Tasks,除了學習體驗之外沒有別的原因。感謝您的理智檢查。 –