C# 使用多个数量有限的线程处理项目列表

C# 使用多个数量有限的线程处理项目列表,c#,.net,multithreading,plinq,parallel-extensions,C#,.net,Multithreading,Plinq,Parallel Extensions,基本上,我希望在多个线程中处理项目列表,而不是一次处理一个。 我只希望一次只运行有限数量的线程。 这种方法有意义吗?对线程计数使用全局变量是唯一的选项吗?(下面是伪代码) 这是有道理的,但我希望您注意到,除非您有非常具体的性能原因或被困在.NET3.5上,否则这不是通常的方法。通常,您会对列表中的元素使用Parallel.ForEach,并依赖于将工作划分为适当的块 即使您没有TPL,也更习惯于将所有工作分开,同时将一大块工作交给每个线程,而不是在线程完成时零碎地分配。按照你的方式做的唯一原因是

基本上,我希望在多个线程中处理项目列表,而不是一次处理一个。 我只希望一次只运行有限数量的线程。 这种方法有意义吗?对线程计数使用全局变量是唯一的选项吗?(下面是伪代码)


这是有道理的,但我希望您注意到,除非您有非常具体的性能原因或被困在.NET3.5上,否则这不是通常的方法。通常,您会对列表中的元素使用
Parallel.ForEach
,并依赖于将工作划分为适当的块

即使您没有TPL,也更习惯于将所有工作分开,同时将一大块工作交给每个线程,而不是在线程完成时零碎地分配。按照你的方式做的唯一原因是,如果你预计一个给定的工作项所花费的时间或多或少是不可预测的,那么你不能提前很好地分配工作

(另外,您可以保留对线程的引用,并检查有多少线程仍在工作,有多少线程已完成。这样就可以删除变量。)

我将使用PLINQ进行此操作,并指定最大并行度,如下所示:

实际上,我正在更改我的答案,因为我意识到您只想直接处理原始列表,而不做任何其他筛选或映射(Where/Select)。在这种特殊情况下,最好使用Parallel::ForEach并通过Parallel选项指定MaxDegreeOfParallelism,如下所示:

 int myMaxDegreeOfParallelism = 4; // read this from config maybe

 Parallel.ForEach(
    list,
    new ParallelOptions
    {
        MaxDegreeOfParallelism = myMaxDegreeOfParallelism
    }
    item =>
    {
        // ... your work here ...
    });

现在,请记住,当您指定这样一个max时,即使资源可用,也会阻止PLINQ使用更多的资源。因此,如果在8核机器上运行,它将永远不会使用超过4个核。相反,仅仅因为您指定了4,并不意味着4保证在任何给定时间同时执行。这完全取决于TPL使用的几种启发式方法,以达到最佳效果。

这方面的机制来自.NET 4.0的OOTB.:)为什么要控制线程数?让框架通过使用来进行最佳决策,这样我就能够在列表中运行并在每个项目上使用QueueUserWorkItem,而不用担心有多少线程正在运行?游泳池能帮我管理吗?有趣的。。。
 int myMaxDegreeOfParallelism = 4; // read this from config maybe

 Parallel.ForEach(
    list,
    new ParallelOptions
    {
        MaxDegreeOfParallelism = myMaxDegreeOfParallelism
    }
    item =>
    {
        // ... your work here ...
    });