在c#中实现大规模并行应用程序的最佳方法



我正在开发一个绑定到网络的应用程序,该应用程序应该有很多(数百个,可能是数千个)并行进程。

我正在寻找实现它的最佳方法。

当我尝试设置时

ThreadPool.SetMaxThreads(int.MaxValue, int.MaxValue);

与创建1000个线程并使这些线程并行工作相比,应用程序的执行变得非常不稳定。

我听说delegate.BeginInvoke在某种程度上比new Thread(...)好,所以我尝试了一下,并在调试器中打开了应用程序,我看到的是并行线程。

如果我必须创建大量的线程,那么确保应用程序平稳运行的最佳方法是什么?

您在C#5/.NET 4.5中尝试过新的await / async模式吗?

我还没有关于它如何在引擎盖下运行的消息来源,但这个新功能最常见的用例之一是等待IO绑定的东西。


线程是而不是轻量级对象。它们的创建和上下文切换成本高昂;因此线程池(预先创建和回收)的原因。大多数涉及网络或其他IO端口的常见解决方案都使用较低级别的IO完成端口(此处有一个托管库)来"等待"端口,但线程可以继续正常执行。

BeginInvoke将使用线程池线程,因此如果有线程可用,它将比仅创建自己的要好。如果使用过多,这种方法可能会立即导致线程不足。

设置这么高的线程池计数从长远来看是行不通的,因为线程太重了,不适合你想要做的事情。


Axum,前微软研究院的一种语言,用于实现适用于此任务的大规模并行性。它的操作类似于Stackless Python或Erlang。Axum的许多概念进入了C#5和.NET 4.5的并行驱动程序。

设置ThreadPool.SetMaxThreads只会影响线程池中有多少线程,而对于您自己使用new thread()创建的线程,它不会产生任何影响。

按照许多人的建议,异步(模型,而不是关键字)。

您应该遵循其他答案和评论中提到的建议。正如fsimonazzi所说,直接创建新线程与ThreadPool无关。为了进行快速测试,请降低最大worker和completionPort线程数,并使用ThreadPool.QueueUserWorkItem方法。ThreadPool将决定您的系统可以处理什么,对任务进行排队,并在可能的时候重新启动线程。

如果您的任务不受计算限制,那么您还应该使用异步I/O。您没有让您的工作线程等待I/O完成。您需要这些工作线程尽快返回池,而不是阻塞I/O请求。

最新更新