Я хотел бы обрабатывать коллекцию параллельно, но у меня проблемы с ее реализацией, поэтому я надеюсь на некоторую помощь.
Проблема возникает, если я хочу вызвать метод, помеченный как async в C #, в лямбда-выражении параллельного цикла. Например:
var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, async item =>
{
// some pre stuff
var response = await GetData(item);
bag.Add(response);
// some post stuff
}
var count = bag.Count;
Проблема возникает, когда счетчик равен 0, поскольку все созданные потоки фактически являются фоновыми потоками, и Parallel.ForEach
вызов не ждет завершения. Если я удалю ключевое слово async, метод будет выглядеть так:
var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, item =>
{
// some pre stuff
var responseTask = await GetData(item);
responseTask.Wait();
var response = responseTask.Result;
bag.Add(response);
// some post stuff
}
var count = bag.Count;
Он работает, но полностью отключает умение ожидания, и мне приходится вручную обрабатывать исключения. (Удалено для краткости).
Как я могу реализовать Parallel.ForEach
цикл, который использует ключевое слово await в лямбде? Является ли это возможным?
Прототип метода Parallel.ForEach принимает Action<T>
параметр as, но я хочу, чтобы он дождался моей асинхронной лямбды.
await
изawait GetData(item)
во втором блоке кода, так как это приведет к ошибке компиляции как есть.Ответы:
Если вам просто нужен простой параллелизм, вы можете сделать это:
Если вам нужно что-то более сложное, посмотрите пост Стивена Туба
ForEachAsync
.источник
dop
задачи, и каждая из них затем последовательно обрабатывает некоторое подмножество входной коллекции.Task.Run
безawait
результата, то это просто бросает работу «выстрелил и забыл» в пул потоков. Это почти всегда ошибка.Вы можете использовать
ParallelForEachAsync
метод расширения из пакета NuGet AsyncEnumerator :источник
maxDegreeOfParallelism
>maxDegreeOfParalellism
С
SemaphoreSlim
его помощью можно добиться контроля параллелизма.источник
Моя легкая реализация ParallelForEach async.
Особенности:
Пример использования:
источник
Я создал для этого метод расширения, который использует SemaphoreSlim, а также позволяет установить максимальную степень параллелизма.
Пример использования:
источник