Merging the results of two background workers upon

2019-05-14 02:01发布

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

2条回答
Ridiculous、
2楼-- · 2019-05-14 02:40

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).

查看更多
Explosion°爆炸
3楼-- · 2019-05-14 02:49

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.

查看更多
登录 后发表回答