I have to work with multiple big 2-dimensional arrays (1024 x 128 for example) and in a section of my code I need to transpose some (up to 12 of them). The procedure takes a fair amount of time and I'm trying to speed it up as much as possible. Knowing that VB.NET supports multi-threading I gave a read here and there to different sources and could come up with the following code in the main subroutine:
RunXTransposingThreads(Arr1, Arr2, Arr3, ...)
Using BackgroundWorker
s as a part of my solution:
Private Sub RunXTransposingThreads(ParamArray ArraysToTranspose() As Array)
Dim x = CInt(ArraysToTranspose.GetLength(0)) - 1
Dim i As Integer
For i = 0 To x
Dim worker As New System.ComponentModel.BackgroundWorker
AddHandler worker.DoWork, AddressOf RunOneThread
AddHandler worker.RunWorkerCompleted, AddressOf HandleThreadCompletion
worker.RunWorkerAsync(ArraysToTranspose(i))
Next
End Sub
Private Sub RunOneThread(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
Dim Transposed(,) As Single = Array.CreateInstance(GetType(Single), 0, 0) ' I need this to be like that in order to use other functions later
Transposed = Transpose2dArray(CType(e.Argument, Single(,)))
e.Result = Transposed
End Sub
Private Sub HandleThreadCompletion(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
Debug.Print("Process complete")
End Sub
Function Transpose2dArray(Of Array)(ByVal inArray As Array(,)) As Array(,)
Dim x = CInt(inArray.GetLength(1))
Dim y = CInt(inArray.GetLength(0))
Dim outArray(x - 1, y - 1) As Array
For i = 0 To x - 1
For j = 0 To y - 1
outArray(i, j) = inArray(j, i)
Next
Next
Transpose2dArray = outArray
End Function
The threads seem to work, because at some point after the execution of RunXTransposingThreads
, I see on my screen a number of "Process complete". The question is: how do I stop the code in main from being executed if I don't have yet transposed arrays?
As others have said, BackgroundWorker is obsolete. Fortunately there are many other modern ways of doing this.
Therefore I won't show you something that makes your code works with BackgroundWorker. Instead I'll show you how to do the same thing by using Tasks, one of those modern ways. Hope it helps.
Function RunXTransposingTasks(ParamArray ArraysToTranspose() As Array) As Array
Dim taskList = New List(Of Task(Of Single(,))) ' our tasks returns Arrays
For Each arr In ArraysToTranspose
Dim r = arr
taskList.Add(Task.Run(Function() Transpose2dArray(r)))
Next
Task.WhenAll(taskList) ' wait for all tasks to complete.
Return taskList.Select(Function(t) t.Result).ToArray()
End Function
Function Transpose2dArray(inArray As Array) As Single(,)
Dim x = inArray.GetLength(1) - 1
Dim y = inArray.GetLength(0) - 1
Dim outArray(x, y) As Single
For i = 0 To x
For j = 0 To y
outArray(i, j) = inArray(j, i)
Next
Next
Return outArray
End Function
' Usage
' Dim result = RunXTransposingTasks(Arr1, Arr2, Arr3, ...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With