Ожидание завершения нескольких Backgroundworkers
Я должен работать с несколькими большими 2-мерными массивами (например, 1024 x 128), и в разделе моего кода мне нужно транспонировать некоторые (до 12 из них). Процедура занимает много времени, и я стараюсь ускорить ее как можно больше. Зная, что VB.NET поддерживает многопоточность я дал прочитать здесь и там в разных источниках и мог придумать следующий код в основной подпрограмме:
RunXTransposingThreads(Arr1, Arr2, Arr3, ...)
используя BackgroundWorker
s как часть моего решение:
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
потоки, кажется, работают, потому что в какой-то момент после исполнение RunXTransposingThreads
, Я вижу на своем экране ряд "процесс завершен". Вопрос в том, как остановить выполнение кода в main, если у меня еще нет транспонированных массивов?
2 ответов
Как говорили другие, BackgroundWorker устарел. К счастью, есть много других современных способов сделать это.
поэтому я не покажу вам то, что заставляет ваш код работать с BackgroundWorker. Вместо этого я покажу вам, как сделать то же самое, используя задачи, один из современных способов. Надеюсь, это поможет.
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, ...)
вы можете попробовать использовать встроенная функция копировать данные
Array.Copy(inArray, outArray, CInt(inArray.GetLength(1)) * CInt(inArray.GetLength(0)))
есть также некоторые пример о том, как использовать Parallel.инструкция foreach.