我正在研究一个网络绑定的应用程序,它应该有很多(数百个,可能是数千个)并行进程。
我正在寻找实施它的最佳方式。
当我尝试设置
时ThreadPool.SetMaxThreads(int.MaxValue, int.MaxValue);
而不是创建1000个线程并使这些线程并行执行,应用程序的执行变得非常紧张。
我听说某个地方delegate.BeginInvoke
在某种程度上比new Thread(...)
更好,所以我尝试过,而不是在调试器中打开应用程序,我看到的是并行线程。< / p>
如果我必须创建大量线程,那么确保应用程序顺利运行的最佳方法是什么?
答案 0 :(得分:8)
您是否在C#5 / .NET 4.5中尝试过新的await / async
模式?
我还没有得到有关如何在幕后操作的消息来源,但这个新功能最常见的用例之一是等待IO绑定的东西。
<小时/> 线程是不轻量级对象。它们的创建和上下文切换成本很高;因此线程池的原因(预先创建和回收)。涉及网络或其他IO端口的大多数常见解决方案利用较低级别的IO完成端口(有一个托管库here)在端口上“等待”,但线程可以继续正常执行。
BeginInvoke
将使用线程池线程,因此如果线程可用,它将比创建自己的 更好。如果使用过多,这种方法可能会立即导致线程不足。
设置如此高的线程池数量从长远来看不会起作用,因为线程对于您想要执行的操作来说太重了。
<小时/> Axum是一种前微软研究语言,曾经用来实现适合这项任务的大规模并行性。它的操作类似于Stackless Python或Erlang。 Axum的许多概念进入了C#5和.NET 4.5的并行驱动。
答案 1 :(得分:2)
设置ThreadPool.SetMaxThreads只会影响线程池的线程数,并且对于使用新的Thread()自己创建的线程不会产生影响。
按照许多人的建议去异步(模型,而不是关键字)。
答案 2 :(得分:0)
您应该遵循其他答案和评论中提到的建议。正如fsimonazzi所说,直接创建新线程与ThreadPool无关。要快速测试,请降低max worker和completionPort线程并使用ThreadPool.QueueUserWorkItem方法。 ThreadPool将决定你的系统可以处理什么,排队任务并尽可能地重新使用线程。
如果您的任务不受计算限制,那么您还应该使用异步I / O.您的工作线程不等待I / O完成。您需要这些工作线程尽快返回池中,而不是阻塞I / O请求。