Parallel.For和/或Parallel.ForEach不产生新线程

时间:2018-07-22 18:37:55

标签: vb.net multithreading parallel-processing task-parallel-library parallel.foreach

出于完整性考虑,我在这里搜索并阅读了其他文章,例如:

Parallel.ForEach not spinning up new threads

但是他们似乎没有解决我的问题,所以我们出发:

我有一个数组结构的Parallel.ForEach,像这样:

Dim opts As New ParallelOptions
opts.MaxDegreeOfParallelism = intThreads

Parallel.ForEach(udtExecPlan, opts,
     Sub(udtStep)
         Dim strItem As String = udtStep.strItem

基本上,对于每个项目,我都会执行一些嵌套循环,最后以这些循环分配作为参数来调用函数。

该函数执行一系列密集的计算(,这会占用该函数的大部分处理时间),并将结果记录在MSSQL表上,如果满足某些条件,该函数将返回True,否则错。如果结果为True,那么我只是从并行函数Sub(udtStep)返回,并且数组中的另一个项应该继续。如果结果为False,则我将简单地遍历最深的嵌套循环的另一次交互,依此类推,努力完成其他外部循环等。因此,简而言之,所有嵌套循环都在主Parallel.ForEach内部循环,就像这样:

Parallel.ForEach(udtExecPlan, opts,
    Sub(udtStep)
        Dim strItem As String = udtStep.strItem

        If Backend.Exists(strItem) Then Return                                                       

        For intA As Integer = 1 To 5
            For intB As Integer = 1 To 50
                Dim booResult As Boolean = DoCalcAndDBStuff(strItem, intA, intB)
                If booResult = True Then Return
            Next intB
        Next intA
    End Sub)

请务必注意,udtExecPlan具有大约585个元素。每个项目需要1分钟到几个小时才能完成。

现在,这是问题所在:

我是否这样做:

Dim opts As New ParallelOptions
opts.MaxDegreeOfParallelism = intThreads

Parallel.ForEach(udtExecPlan, opts,

其中intThreads是核心计数,或者是我分配给它的任何数字(尝试5、8、62、600),或者我是否只是忽略了整个ParallelOptions声明并从Parallel.ForEach语句中选择,我都注意到了将增加我指定的尽可能多的线程,直至系统中内核的总数(包括HT内核)。很好,一切都很好。

例如,在具有32个核心/ 64个HT核心和128GB RAM的HP DL580G7服务器上,我可以在任务管理器上看到5、8、62或64个线程(使用600选项),这就是我的任务。 d期望。

但是,在处理数组中的项目时,任务管理器上的线程“消失”(从大约75%的利用率变为0%),并且永远不会再旋转,直到只有1个线程在工作。例如,如果我将intThreads设置为62(如果我省略了整个ParallelOptions声明并从Parallel.ForEach语句中选择,则设置为无限),我可以在db表上看到已经处理了62(或64)个项目,但是从那时起上,它一次又回到1个线程和1个项目。

我期望一个项目完成后就可以启动一个新线程,因为大约有585个项目需要处理。几乎是并行完成62或64个项目,然后仅完成一项,直到完成为止,这使得整个服务器此后几乎处于空闲状态。

我想念什么?

我用主Parallel.For循环(没有其他外部循环,如本例所示)尝试了其他一些不同的过程,并获得了相同的行为。

为什么?欢迎任何想法。

我正在将VS.NET 2015与.NET Framework 4.6.1,W2K8R2完全修补。

谢谢!

0 个答案:

没有答案