3

私は2つのバックグラウンドスレッドを持っています

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

ワーカー スレッドの両方のメソッドがデータ テーブルを返している

今私の仕事は、これらの 2 つのデータ テーブルを 1 つにマージする必要があることです。

そのため、最初のタスクの RunCompletion でこれを行っています

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

しかし、何らかの理由で do while ループが無限ループになっているようです。スレッドは終了しません。誰かが私が間違っていることを教えてもらえますか。または、データをマージできるように、2 番目のワーカー スレッドが完了するのを待つより良い方法はありますか。任意の助けをいただければ幸いです

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.RunBackgroundWorkerはあらゆる点で優れており、これは複雑なことを行う場合 (つまり、2 つのバックグラウンド操作を調整する場合) に特に顕著です。

于 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 に答える