#c# #asynchronous #foreach #parallel-processing #queue
#c# #асинхронный #foreach #параллельная обработка #очередь
Вопрос:
Я должен выполнять метод ‘x’ раз параллельно.Этот метод в основном вызывает службы отчетов SQL Server для создания отчета, поэтому у меня есть список — скажем, 200 отчетов — для генерации.
Время, затрачиваемое методом (генерация отчета), зависит от полученных входных параметров: иногда это занимает 1 секунду, иногда 50 секунд, 2 минуты и т.д..
У меня есть коллекция отчетов для генерации ( _distinctReports
), поэтому я вызвал Parallel.ForEach
отправку коллекции с a MaxDegreeOfParallelism
= 8:
Parallel.ForEach(_distinctReports, new ParallelOptions { MaxDegreeOfParallelism = _maxDegreeOfParallelism }, ExecuteReport);
Я заметил, что каким-то Parallel.ForEach
образом вызывает «пакеты» из 8 элементов одновременно (в зависимости от процессора сервера это может отличаться, но на сервере, который я тестирую, всегда обрабатывается 8) и отправляет еще один пакет из 8 только после завершения предыдущих 8, что является большой проблемой в моем случаепозвольте мне рассказать, почему:
Если пакет содержит 7 отчетов, сгенерированных за 1 секунду каждый, плюс один отчет за 2 минуты, мне нужно подождать целых 2 минуты, пока не будет запущен следующий пакет из 8 Parallel.ForEach
.
Я хотел бы иметь очередь из 8 (другого желаемого количества), которая постоянно заполняется большим количеством элементов для обработки, как только появятся доступные слоты (а не блоки по 8).
Как я могу выполнить это на C #? Я читал об очередях, но не смог придумать дизайн, соответствующий моим требованиям.
Комментарии:
1. » Этот метод в основном вызывает службы отчетов SQL Server для создания отчета » Звучит так, как будто это должно быть асинхронным, а не параллельным. Это
ExecuteReport
async
метод?2. Нет не является асинхронным. Я рассматриваю этот вариант, но помните, что я не хочу, чтобы одновременно обрабатывалось более 8 отчетов
3. Параллелизм также
async
может быть ограничен. Если это процесс, который включает в себя ввод-вывод, то вы получите мало пользы от параллелизма.4. Спасибо @JohnathanBarclay, я посмотрю. Более того, отчеты генерируются на другом сервере, и они обычно невелики по размеру, но логика извлечения данных на уровне SSRS может быть там очень медленной, поэтому не так много пользы в операциях ввода-вывода.
5. AFAIK
Parallel.ForEach
не ведет себя так, как вы описываете. Он ведет себя ожидаемым образом. Так что, вероятно, происходит что-то еще. Не могли бы вы попробовать вызватьThreadPool.SetMinThreads(100, 100);
в начале программы, чтобы убедиться, что вы не ограниченыThreadPool
доступностью?