Объедините результат двух параллельных задач в одном списке

Я хочу объединить результат из двух задач в одной коллекции List.

Убедитесь, что - я хочу запускать оба метода параллельно.

код:

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

Метод 1:

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

Метод2:

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

Теперь я хочу сохранить результат этих двух методов в поле totalEmployees, также эти два метода должны выполняться асинхронно.

Ответ 1

В то время как многие ответы близки, самый чистый и самый эффективный вариант использует Task.WhenAll в сочетании с SelectMany:

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

Ответ 2

Вы можете использовать Task.WhenAll, чтобы создать задачу, которая вернется, когда все поставленные задачи будут завершены

var result = await Task.WhenAll(SearchEmployeeFromDb(),GetEmployeeFromService());
var combined = result[0].Concat(result[1]);

Ответ 3

  • Запустите обе задачи
  • Используйте Task.WhenAll, чтобы дождаться завершения обеих задач.
  • Используйте Enumerable.Concat для объединения результатов


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

await Task.WhenAll(searchEmployeesTask, getEmployeesTask);

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

Ответ 4

Что-то вроде этого должно работать:

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

await Task.WhenAll(t1, t2)

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

Ответ 5

Используйте 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);

... или использовать любой способ, которым вы хотите объединить два списка.

Я обновил решение, не нужно было создавать список, а затем добавить первый результат. Мы ждем завершения первого метода, а затем создадим список.