Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Waiting for multiple Backgroundworkers to complete

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 BackgroundWorkers 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?

like image 701
Noldor130884 Avatar asked Jan 31 '18 13:01

Noldor130884


1 Answers

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, ...)
like image 72
Kul-Tigin Avatar answered Nov 15 '22 09:11

Kul-Tigin