См. следующий параллельный анализ производительности, представляющий работу, выполняемую параллельным foreach:
Внутри цикла каждый поток считывает данные из БД и обрабатывает его. Между потоками нет блокировок, так как каждый обрабатывает разные данные.
Похоже, что во всех потоках foreach есть периодические блокировки по неизвестным причинам (см. черные вертикальные прямоугольники). Если вы видите выбранный заблокированный сегмент (темно-красный), вы увидите, что стек показывает поток, заблокированный в конструкторе StockModel.Quotation. В коде есть только два пустых списка!
Я где-то читал, что это может быть вызвано GC, поэтому я изменил сборку мусора для запуска в режиме сервера с помощью:
<runtime>
<gcServer enabled="true"/>
</runtime>
У меня небольшое улучшение (примерно на 10% - на 15% быстрее), но у меня все еще есть вертикальные замки повсюду.
Я также добавил ко всем БД запросы WITH (NOLOCK), поскольку я только читаю данные без каких-либо различий.
Любой намек на то, что происходит здесь?
Компьютер, на котором выполнен анализ, имеет 8 ядер.
РЕДАКТИРОВАТЬ: После включения серверов Microsoft Symbol получается, что все потоки заблокированы для вызовов, таких как wait_gor_gc_done или WaitUntilGCComplete. Я думал, что для включения GCServer у меня был один GC для каждого потока, поэтому я бы избегал "вертикальной" блокировки, но, похоже, это не так. Я не прав?
Второй вопрос: поскольку машина не находится под давлением памяти (используется 5 из 8 концертов), есть способ отсрочить выполнение GC или приостановить его до тех пор, пока параллельный выходной сигнал не будет (или настроить его на то, чтобы срабатывать реже)