web-dev-qa-db-ja.com

2つの並列タスクの結果を1つのリストにまとめます

2つのタスクの結果を1つのリストコレクションにまとめたいと思います。

確認してください-両方のメソッドを並行して実行したいです。

コード:

List<Employee> totalEmployees = new List<Employee>();

方法1:

public async Task<IEnumerable<Employee>> SearchEmployeeFromDb();

方法2:

public async Task<IEnumerable<Employee>> GetEmployeeFromService();

ここで、これら2つのメソッドの結果をtotalEmployeesフィールドに保持したいと思います。また、これら2つのメソッドは非同期で実行する必要があります。

14
nunu

多くの答えが近いですが、最もクリーンで最も効率的なオプションは、Task.WhenAllSelectManyと組み合わせて使用​​することです。

async Task<IEnumerable<Employee>> Combine()
{
    var results = await Task.WhenAll(SearchEmployeeFromDb(), GetEmployeeFromService());
    return results.SelectMany(result => result);
}

これは、並行してあなたが同時に意味することを前提としています。これらの操作を最初から複数のスレッドで実行する場合(asyncメソッドの同期部分を含む)、Task.Runを使用して作業をThreadPoolスレッドにオフロードする必要もあります。 :

private async Task<IEnumerable<Employee>> Combine()
{
    var results =
        await Task.WhenAll(Task.Run(() => SearchEmployeeFromDb()), Task.Run(() => GetEmployeeFromService()));
    return results.SelectMany(result => result);
}
25
i3arnon

Task.WhenAll 提供されたすべてのタスクが完了したときに返されるタスクを作成します

var result = await Task.WhenAll(SearchEmployeeFromDb(),GetEmployeeFromService());
var combined = result[0].Concat(result[1]);
1
Jamiec
  • 両方のタスクを開始します
  • 使用する Task.WhenAll両方のタスクが終了するのを待つ
  • 使用する Enumerable.Concat結果を組み合わせる


var searchEmployeesTask = SearchEmployeeFromDb();
var getEmployeesTask = GetEmployeeFromService();

await Task.WhenAll(searchEmployeesTask, getEmployeesTask);

var totalEmployees = searchEmployeesTask.Result.Concat(getEmployeesTask.Result);
1
dcastro

このようなものが機能するはずです:

var t1 = SearchEmployeeFromDb()
var t2 = GetEmployeeFromService()

await Task.WhenAll(t1, t2)

// Now use t1.Result and t2.Result to get `totalEmployees`
0
Richard

デッドロックを回避し、タスクを定義し、実行してから待機するには、ConfigureAwait(false)を使用します。

var fromDbTask = SearchEmployeeFromDb().ConfigureAwait(false);
var fromServiceTask = GetEmployeeFromService().ConfigureAwait(false);

var fromDbResult = await fromDbTask;
var totalEmployees = new List(fromDbResult);

var fromServiceResult = await fromServiceResult;
totalEmployees.AddRange(fromServiceResult);

...または、2つのリストをマージする方法を使用します。

ソリューションを更新しました。リストを作成してから最初の結果を追加する必要はありませんでした。最初のメソッドが終了するのを待ってから、リストを作成します。

0
Cybrosys