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