Объедините результат двух параллельных задач в одном списке
Я хочу объединить результат из двух задач в одной коллекции 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);
... или использовать любой способ, которым вы хотите объединить два списка.
Я обновил решение, не нужно было создавать список, а затем добавить первый результат. Мы ждем завершения первого метода, а затем создадим список.