.Net 4.0 Параллельный цикл foreach не может порождать новые потоки в «производственном» приложении - PullRequest
2 голосов
/ 03 апреля 2012

У меня есть небольшое приложение WPF C #, в основе которого лежит параллельный цикл foreach. Фактический цикл не требует особого ожидания ответа от сети (в основном это сетевой сканер), и он отлично работает, выполняя его в Visual Studio 2010 - приложение будет наращивать до сотен потоков, даже тысяч, если я позволю бежать достаточно долго.

Вот основной бит кода:

ParallelOptions parallelOptions = new ParallelOptions();
        parallelOptions.MaxDegreeOfParallelism = 4; // I've tried changing this all the way up to the maximum

        ThreadPool.SetMinThreads(100, 100);

        Parallel.ForEach<string>(scanAddresses, parallelOptions,  (toscan,state) =>
 {
    doMyScan(toscan);
 }

Однако, когда я «публикую» его как приложение «ClickOnce», приложение не работает с многопоточностью, или вообще не работает, на некоторых машинах - число потоков никогда не превышает 16 потоков независимо от того, как долго это осталось. Я не могу точно определить, что является общим знаменателем - я исключил ОС (например, XP против Win7), процессоры, память и 32-разрядную или 64-разрядную. Приложение даже плохо себя ведет, когда я загружаю его в свою виртуальную машину разработки с рабочего сервера - поэтому то же самое приложение и код, который летит под VS2010, сканирует при запуске «вживую» на точно той же самой коробке, в которой оно было разработано на , Но на других машинах он работает так, как задумано, порождая множество потоков, даже на самых ограниченных установках XP.

Я почти уверен, что основной код исправен - в конце концов, он отлично работает на НЕКОТОРЫХ машинах, и у меня есть вариант того же кода, который отлично работает как консольное приложение - так что это что-то в процессе развертывания, которое его нарушает , Кто-нибудь может подсказать, как начать устранение неполадок с этим?

Ответы [ 3 ]

4 голосов
/ 03 апреля 2012

TPL не нацелен на создание максимального количества потоков. Он нацелен на получение оптимального количества потоков, и это зависит от количества ядер на машине и текущей нагрузки. Нет смысла создавать дополнительные потоки, когда текущие ядра насыщены, потому что это только снизит производительность программы. Я не уверен, как вам удается создавать тысячи потоков в любой среде, используя Parallel Foreach.

Также TPL следует использовать для работы с интенсивным использованием процессора, а не для ожидания.

0 голосов
/ 03 апреля 2012

Ну ... в конце концов оказалось, что это не имеет ничего общего с параллелизмом (хотя спасибо за комментарии ниже, они сделали интересное чтение - я определенно не эксперт, я просто пахал, и это, казалось, работало; )).

Проблема была ограничена полуоткрытыми TCP-соединениями; Я знал, что этот предел существует в XP, но хотя он, по-видимому, был удален в Win7, ему все еще нужен ключ реестра (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\ EnableConnectionRateLimiting), чтобы действительно удалить его. Что еще странно, ограничение на полураскрытие не распространялось на приложение, работающее под VS - оно ограничивало соединения только тогда, когда оно работало как «настоящее», автономное приложение. Все очень странно, но проблема все равно решена - спасибо за все отзывы!

0 голосов
/ 03 апреля 2012

У меня сложилось впечатление, что библиотеки Parallel смотрят на ваше базовое аппаратное обеспечение (процессоры и ядра), чтобы определить, какую степень параллелизма следует использовать, если она вообще есть ... Возможно, машины, которые работают некорректно, имеют только один процессор, одноядерные?

...