2009-11-30 44 views
1

我創建共享一個事件處理這樣的BackgroundWorker的數組:創建在C#在運行時事件處理

BackgroundWorker[] workers = new BackgroundWorker[files.length]; 

for(int i = o; i<files.length; i++) 
{ 
     workers[i] = new BackgroundWorker(); 
     workers[i].DoWork += new DoWorkEventHandler(worker_DoWork); 
     workers[i].RunWorkerCompleted += newRunWorkerCompletedEventHandler(worker_RunWorkerCompleted); 
     workers[i].RunWorkerAsync(files[i]); 
} 

所有工人都共享同一個事件,其做同樣的事情,只能用不同的參數和結果像這樣:

private void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
     e.Result = ComputeSomething(e.Argument.ToString()); 
} 

private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
      resultArray.Add(e.Result); 
} 

private int ComputeSomething(string file) 
{ 
     ... 
     return number; 
} 

很顯然,在代碼中,我試圖讓運行asyncronously BackgroundWorker的名單,但是,當我檢查的結果,他們中的一些是不正確的。我猜測「e.result」的值被其他工作人員所取代,因爲他們共享相同的事件處理程序,如果是這種情況,那麼我想爲每個BackgroundWorker創建個別事件處理程序,以便e.result的值將不會被取代。我將如何做到這一點?

+1

如果所有後臺工作人員都使用相同的EventArgs,則會出現問題。您的邏輯中可能存在問題,您在RunWorkerCompleted中收到的結果究竟有什麼問題? – 2009-11-30 15:17:07

+1

你如何「檢查結果」?你是否依賴'resultArray'中的結果順序? – 2009-11-30 15:19:00

+1

你的代碼在計算東西時也可能是一個問題,因爲它可能需要同步。 – rerun 2009-11-30 15:19:53

回答

7

嘗試同步訪問resultArray:


private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    lock(resultArray) 
     resultArray.Add(e.Result); 
} 
+0

我加了鎖,它現在正在工作。謝謝。 – murasaki5 2009-11-30 16:37:45

1

共享同一個事件處理方法不應該是一個問題 - 這是它提供了「E」,在其中您存儲結果BackgroundWorker

另一方面,你從多個線程訪問resultArray。這可能會導致問題。你在結果中看到什麼樣的錯誤?除了最後結合結果的方式之外,我希望它沒問題。

1

我不明白e.Result如何被其他工人取代。 當你說某些結果不正確時,你的意思是這個值是錯誤的,沒有任何價值,或者某些結果是重複的,而其他的結果是消失的? 在我看來,當添加到resultsArray以確保它是線程安全的時,您應該添加一個synclock。