У меня есть следующий оператор PLINQ в программе на C #:
foreach (ArrestRecord arrest in
from row in arrestQueue.AsParallel()
select row)
{
Geocoder geocodeThis = new Geocoder(arrest);
writeQueue.Enqueue(geocodeThis.Geocode());
Console.Out.WriteLine("Enqueued " + ++k);
}
И arrestQueue
, и writeQueue
ConcurrentQueues .
Ничего не выполняется вПараллельно:
- Во время работы общее использование ЦП составляет около 30%, и это также относится ко всему остальному.У меня 8 ядер (Hyper-Threading на Core i7 720QM с 4 физическими ядрами), и 4 из 8 ядер практически не используются.Остальные работают примерно на 40% -50%.
- Использование диска обычно составляет 0%, и использование сети отсутствует, за исключением запросов к базе данных Postgres на localhost (см. Ниже).
- Если ядобавить точку останова где-то внутри
geocodeThis.Geocode()
, в раскрывающемся списке Thread Visual Studio просто говорится [ pid ] Основной поток .Он никогда не переходит в какой-либо другой поток. - Я использую Npgsql для подключения к Postgres, и каждый поток выполняет несколько SELECT запросов к таблице.Я запускаю приложение pgAdmin III «Состояние сервера», которое показывает pg_stat_activity .Наблюдая за этим и размещением стратегических точек останова (см. Выше), я вижу, что приложение никогда не имеет более одного открытого подключения к базе данных для всех якобы одновременных потоков, работающих
geocodeThis.Geocode()
.Даже если я добавлю Pooling = false в строку подключения к БД, чтобы принудительно не объединять подключения, я никогда не увижу более 1 подключения, используемого в geocodeThis.Geocode()
. - Таблица Postgresиндексируется в каждом столбце в предложении WHERE .Даже если бы он был плохо проиндексирован, я бы ожидал много использования диска.Если бы Postgres держал вещи каким-либо другим способом, похоже, что это впитало бы ядро.
Это похоже на простое исследование PLINQ, и я ломаю голову над тем, почему ничего не работает параллельно.