我有一个小型的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个线程,无论多长时间's left. I can'确切地知道什么是常见的分母是 - I 've ruled out the OS (eg XP vs Win7), processors, memory, and whether it' s 32或64位 . 当我从 生产环境 服务器将应用程序下载到我的开发虚拟机时,应用程序甚至行为不当 - 因此,在与开发时完全相同的框上运行"live"时,在VS2010下运行的相同应用程序和代码会爬行 . 但在其他机器上,它按设计运行,产生大量线程,即使在最有限的XP安装中也是如此 .
我非常确定核心代码是合理的 - 毕竟,它在某些机器上工作正常,并且我有一个相同代码的变体运行良好的控制台应用程序 - 所以它是关于部署过程的一些东西正在打破它 . 任何人都可以建议如何开始排除故障?
3 回答
TPL不旨在产生最大线程数 . 它旨在产生最佳线程数,这取决于机器上的核心数量和当前负载 . 当前核心饱和时产生额外线程没有意义,因为这只会降低程序的性能 . 我不确定您是如何使用Parallel Foreach在任何环境中生成数千个线程的 .
此外,TPL应该用于CPU密集型工作而不是等待 .
我一直认为并行库会查看您的底层硬件(处理器和内核),以确定在任何情况下采用何种程度的并行性......也许那些行为不端的机器只有单处理器,单核?
嗯...毕竟它与并行性无关(尽管感谢下面的评论,他们做了有趣的阅读 - 我自己绝对不是专家,我只是犁过它似乎工作;)) .
问题是半开TCP连接的限制;我知道这个限制存在于XP上,但即使它在Win7中显然已被删除,它仍然需要一个注册表项(
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\ EnableConnectionRateLimiting
)来真正删除它 . 更奇怪的是,半开的限制不适用于在VS下运行的应用程序 - 它仅限制了作为独立应用程序运行的连接 . 一切都很奇怪,但问题无论如何都要解决了 - 感谢所有的反馈!