为了完整起见,我在这里搜索并阅读了其他文章,例如:

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

基本上,对于每个项目,我做一些嵌套循环,最后调用一个函数,将这些循环赋值作为参数 .

该函数执行一系列强烈的计算( which takes up most of the function's processing time )并将结果记录在MSSQL表中,如果满足某些条件,则函数返回True,否则返回False . 如果结果为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选项)线程忙,这是我所期望的 .

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

我期待一个项目完成后新的线程会被旋转,因为有大约585个项目要经过 . 几乎就好像62或64个项目并行完成,然后只有1个项目直到完成,这使整个服务器几乎空转 .

我错过了什么?

我已尝试使用一个主要的Parallel.For循环(没有其他外部循环存在,就像在此示例中)并获得相同的行为 .

为什么?欢迎任何想法 .

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

谢谢!