Parallel.ForEach不工作,而正常For Each循环是

时间:2018-02-01 08:42:30

标签: arrays vb.net multithreading lambda parallel-processing

标题非常自我解释。我有一些代码在顺序执行时有效,如果我使用Parallel循环则没有。我用

来称呼它
RunXTransposingThreads(Arr1, Arr2, Arr3, Arr4)

成为Arr s Dim Arr1(,) As Single = Array.CreateInstance(GetType(Single), 1025, 129)

Sub RunXTransposingThreads(ParamArray ArraysToTranspose() As Array)

    Parallel.ForEach(Of Array)(ArraysToTranspose,
        Sub(inArray)
            Dim x As Integer = CInt(inArray.GetLength(1))
            Dim y As Integer = CInt(inArray.GetLength(0))
            Dim outArray(,) As Single = Array.CreateInstance(GetType(Single), x, y)
            For i As Integer = 0 To x - 1
                For j As Integer = 0 To y - 1
                    outArray(i, j) = inArray(j, i)
                Next
            Next
            inArray = Array.CreateInstance(GetType(Single), x, y)
            Array.Copy(outArray, inArray, inArray.Length)
        End Sub)

我尝试使用Function而不是Sub,但没有任何效果。 ArrayToTranspose() Array中的所有元素都未在主子例程中转置,这意味着Arr1之前的RunXTransposingThreads与该行之后的For Each相同。

如果我使用正常的Oracle DB周期,那么一切都很完美。

2 个答案:

答案 0 :(得分:3)

你需要摆脱这条线:

inArray = Array.CreateInstance(GetType(Single), x, y)

它覆盖了本地引用inArray(作为参数传入)并导致新值不能使其脱离匿名方法块。 inArray已经创建,重用实例不是问题,并允许修改后的数组使其脱离方法。

答案 1 :(得分:2)

不是尝试从Parallel循环返回一个数组数组,而是创建本地副本以在一些嵌套的Parallel.For循环中进行转置并返回对我来说更有意义。

最后你已经使用For循环而不是For Each了。

Private Function RunXTransposingThreadsParallel(ParamArray ArraysToTranspose() As Array) As Array
    Dim transposedOnes(arraysToTranspose.Length - 1) As Array

    Parallel.For(0, arraysToTranspose.Length, Sub(i) ' Loop #1
        Dim x = arraysToTranspose(i).GetLength(0)
        Dim y = arraysToTranspose(i).GetLength(1)
        transposedOnes(i) = New Single(y - 1, x - 1){}
        Parallel.For(0, x, Sub(xl) ' Loop #2
            Parallel.For(0, y, Sub(yl) ' Loop #3
                transposedOnes(i)(yl, xl) = arraysToTranspose(i)(xl, yl)
            End Sub)
        End Sub)
    End Sub)

    Return transposedOnes
End Function

' Usage
' Dim result = RunXTransposingThreadsParallel(Arr1, Arr2, Arr3, Arr4)