2011-11-11 30 views
2

我不是最好的多線程,這有點複雜,所以希望我能解釋得很好。C#在BackgroundWorker內異步工作?

基本上,我擁有的是一個BackgroundWorker任務,它內部有幾個調用來從網站檢索信息。可能有更好的方法來做到這一點,但我想不出一個。我這樣做的原因是因爲我希望有一個單獨的事件,因爲當所有對網站的調用(以及後續的信息處理)完成時。

這基本上就是我所回事:

private void loadContent() { 
    BackgroundWorker worker = new BackgroundWorker(); 
    worker.DoWork += delegate(object sender, DoWorkEventArgs e) { 
     getAndProcessInformation(desiredInformationName); 
     getAndProcessInformation(someOtherDesiredInformationName); 
    }; 
    worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) { 
     MessageBox.Show("Finished!"); 
     Dispatcher.BeginInvoke(() => { progressBar(false); }); 
    }; 
    worker.RunWorkerAsync(); 
} 
private void getAndProcessInformation(string theInformationIWant){ 
    Fetcher dataFetcher = new Fetcher(); //Fetcher is a custom class that reads information from a web server 
    dataFetch.receivedData += delegate(DataResponseArgs args) { 
     //Process some data 
    }; 
    dataFetch.requestData(theInformationIWant); 
} 

那麼,什麼情況是,RunWorkerCompleted在兩個getAndProcessInformation方法被調用後立即調用,而之前的數據是實際完成處理。有什麼辦法可以讓RunWorkerCompleted只在方法中的處理實際完成後才運行?

現在,我可以看到BackgroundWorker並不是真的必要,因爲處理實際上已經在單獨的線程中完成了,但我不知道任何可以讓我得到期望結果的方法所有處理完成後觸發事件。所以,我想這確實是兩個問題。我應該繼續使用BackgroundWorker嗎?如果是的話,我應該如何解決它,或者,如果不是,還有什麼替代方案?

回答

1

如果您的Fetcher已經創建了自己的線程,那麼使用BackgroundWorker並沒有像您已經想到的那麼有意義。

由於您尚未共享Fetcher的實現。它可能應該是這樣的,如果你要堅持你已經擁有

private void getAndProcessInformation(string theInformationIWant){ 
    Fetcher dataFetcher = new Fetcher(); 
    var eventHandle = new ManualResetEvent(false); 
    dataFetch.receivedData += delegate(DataResponseArgs args) { 
     //Process some data 
     eventHandle.Set(); 
    }; 
    dataFetch.requestData(theInformationIWant); 
    eventHandle.WaitOne(); 
} 

這樣的功能getAndProcessInformation不會返回,直到處理已經完成。一次只能有一個Fetch工作。

如果你想要所有的Fetchers並行工作,你已經刪除了WaitOne並讓getAndProcessInformation返回等待句柄。然後在DoWork你可以做一個等待所有的手柄信號。

+0

太棒了,謝謝! –