3

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

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

当我尝试设置

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

与创建 1000 个线程并让它们并行执行相比,应用程序的执行变得非常复杂。

我听说过某处delegate.BeginInvoke更好new Thread(...),所以我尝试了它,然后在调试器中打开了应用程序,我看到的是并行线程。

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

4

3 回答 3

8

您是否尝试过await / asyncC# 5 / .NET 4.5 中的新模式?

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


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

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

从长远来看,设置如此高的线程池计数是行不通的,因为线程对于你想要做的事情来说太重了。


Axum 是一种前 Microsoft Research 语言,用于实现适合此任务的大规模并行性。它的操作类似于 Stackless Python 或 Erlang。来自 Axum 的许多概念进入了 C# 5 和 .NET 4.5 的并行驱动。

于 2012-11-16T16:25:40.273 回答
2

设置 ThreadPool.SetMaxThreads 只会影响线程池有多少线程,并且不会对您使用 new Thread() 创建的线程产生影响。

正如许多人所建议的那样去异步(模型,而不是关键字)。

于 2012-11-16T16:48:53.253 回答
0

您应该遵循其他答案和评论中提到的建议。正如 fsimonazzi 所说,直接创建新线程与 ThreadPool 无关。为了快速测试,降低最大工作线程和完成端口线程并使用ThreadPool.QueueUserWorkItem方法。ThreadPool 将决定您的系统可以处理什么,将您的任务排队并尽可能重用线程。

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

于 2012-11-16T17:55:04.820 回答