我在C#中有一个应用程序列表,其中包含要执行的工作列表。我希望尽可能多地同时完成这项工作。但是,我需要能够控制并行任务的最大数量。
根据我的理解,这可以通过ThreadPool或任务来实现。我使用哪一个有区别吗?我主要担心的是能够一次控制多少个线程处于活动状态。
答案 0 :(得分:20)
请查看Task
的{{3}}。
我建议你使用Tasks,因为它们提供比ThreadPool更高级别的抽象。
可以找到关于该主题的非常好的读物ParallelOptions.MaxDegreeOfParallelism。真的,一本必备的书,它是免费的:)
答案 1 :(得分:5)
在TPL中,您可以使用ParallelEnumerable
或WithDegreeOfParallelism
ParallelOptions.MaxDegreeOfParallism
如果您只使用自定义线程或任务,还有CountdownEvent
可能是更好的选择。
在ThreadPool
中,当AppDomain
使用SetMaxThreads
全局代码时,您可能会不必要地限制不相关的代码。
您不能将工作线程数或I / O完成线程数设置为小于计算机中处理器数的数字。
如果托管公共语言运行库,例如Internet信息服务(IIS)或SQL Server,则主机可以限制或阻止更改线程池大小。
更改线程池中的最大线程数时请小心。虽然您的代码可能会受益,但更改可能会对您使用的代码库产生负面影响。
将线程池大小设置得太大会导致性能问题。如果同时执行的线程太多,则任务切换开销成为一个重要因素。
我同意另一个答案,你应该在ThreadPool
上使用TPL作为多线程的更好抽象,但它可以在两者中实现你想要的。
答案 2 :(得分:3)
在这个article on msdn中,他们解释了为什么他们推荐Tasks而不是ThreadPool for Parallelism。
答案 3 :(得分:3)
任务对我来说有一个非常迷人的特点,你可以建立任务链。哪个是在之前的任务的某些结果上执行的。 我经常使用的一个功能如下:任务A在后台运行以执行一些长时间运行的工作。我在它之后链接任务B,仅在任务A完成常规时执行并且我将其配置为在前台运行,因此我可以使用长时间运行的任务A的结果轻松更新我的控件。
答案 4 :(得分:2)
您还可以创建一个信号量来控制一次可以执行的线程数。您可以创建一个新的信号量,并在构造函数中指定一次可以同时使用该信号量的同时线程数。由于我不知道你将如何使用线程,这将是一个很好的起点。
MSDN Article on the Semaphore class
-Wesley