3

我有两个后台线程

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();

工作线程中的两个方法都返回数据表

现在我的任务是我需要将这两个数据表合并为一个

出于这个原因,我在第一个任务的 RunCompletion 中执行此操作

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

但由于某种原因,do while 循环似乎处于无限循环中。线程没有结束。有人可以告诉我我做错了什么。还是有更好的方法来等待第二个工作线程完成,以便我可以合并数据。任何帮助,将不胜感激

4

2 回答 2

4

现在 .NET 4.5 已经发布,我建议大家使用Task.Run而不是BackgroundWorker,如下所示:

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

Task.Run在各方面都优于BackgroundWorker,这在做任何复杂的事情(即协调两个后台操作)时尤其明显。

于 2013-09-06T13:52:55.547 回答
3

我建议改用 TPL,使其更具可读性:

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

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

  //merge

});

await Task.WhenAll()...如果您希望主线程(异步)等待表被合并,您也可以这样做。

确保将Query方法更改为以下内容:

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

编辑 我刚刚注意到这可能会出错。

ContinueWith 任务(很可能)不会在 UI 线程中运行。

如果您需要在 UI 线程中合并表,那么您应该这样做:

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

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

这样,该MergeTables()方法将在 UI 线程上运行。

于 2013-09-06T13:41:39.613 回答