Merging the results of two background workers upon completion

浪尽此生 提交于 2020-01-23 11:12:44

问题


i have two background threads

Worker = new BackgroundWorker();
Worker.DoWork += new DoWorkEventHandler(GetQuery);
Worker.RunWorkerCompleted += GetQuery_RunWorkerCompleted;
Worker.RunWorkerAsync();

Worker2012 = new BackgroundWorker();
Worker2012.DoWork += new DoWorkEventHandler(GetQuery2012);
Worker2012.RunWorkerCompleted += GetQuery2012_RunWorkerCompleted;
Worker2012.RunWorkerAsync();

both the methods in worker threads are returning data tables

now my task is i need to merge those two data tables into one

for that reason i am doing this in the RunCompletion of the first task

void GetQuerys_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
   do{} while(Worker2012.IsBusy);
   //Merge Datatables
}

but for some reason the do while loop seems to be in infinite loop. the thread does not end. can some one tell me what i am doing wrong. or is there a better way to wait for the second worker thread to get complete so that i can merge data. any help would be appreciated


回答1:


Now that .NET 4.5 is out, I recommend that everyone use Task.Run instead of BackgroundWorker, as such:

var task1 = Task.Run(() => GetQuery());
var task2 = Task.Run(() => GetQuery2012());
var dataTables = await Task.WhenAll(task1, task2);
// Merge databases

Task.Run is superior to BackgroundWorker in every way, and this is particularly noticeable when doing anything complex (i.e., coordinating two background operations).




回答2:


I'd recommend using TPL instead, making it much more readable:

Task query1 = GetQuery();
Task query2 = GetQuery2012();

Task.WhenAll(query1, query2).ContinueWith( t => {

  //merge

});

You can also do await Task.WhenAll()... if you want the main thread to (asynchronously) wait for the tables to be merged.

Make sure you change your Query methods to something like this:

public Task GetQuery() {
  return Task.Run( () => {
    //do background work
  });    
}

Edit I just noticed something that might go wrong with this.

The ContinueWith task will (most likely) not run in the UI thread.

If you need to merge the tables in the UI thread, then you should do this instead:

public void UIMethod() {
    Task query1 = GetQuery();
    Task query2 = GetQuery2012();

    await Task.WhenAll(query1, query2); //will free the thread until both tasks complete
    MergeTables();
}

This way, the MergeTables() method will run on the UI thread.



来源:https://stackoverflow.com/questions/18659124/merging-the-results-of-two-background-workers-upon-completion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!