如何等待所有线程要完成而不阻塞在VB.NET的用户界面?

问题描述 投票:0回答:1

我有一个VB.NET框架4.0应用程序中的一个大的初始化程序,我想以优化运行时间。作为大多数计算机时下能够一次执行多个线程的,我想介绍多线程来执行非依赖并联,所以给用户的总时间花费初始化应用程序被降低。

原来(单线程)实施看起来是这样的:

Friend Module MainModule

    Friend Sub Main()
        LongRunningInitialization1()
        LongRunningInitialization2()
        LongRunningInitialization3()
        LongRunningInitialization4()
        LongRunningInitialization5()
        LongRunningInitialization6()
        LongRunningInitialization7()
    End Sub

    Private Sub LongRunningInitialization1()
    End Sub

    Private Sub LongRunningInitialization2()
    End Sub

    Private Sub LongRunningInitialization3()
    End Sub

    Private Sub LongRunningInitialization4()
    End Sub

    Private Sub LongRunningInitialization5()
    End Sub

    Private Sub LongRunningInitialization6()
    End Sub

    Private Sub LongRunningInitialization7()
    End Sub

End Module

我的第一个方法是为使用System.Threading.Thread并行工作负载:

Friend Sub Main()
    Dim thread1 As New Threading.Thread(AddressOf LongRunningInitialization1)
    Dim thread2 As New Threading.Thread(AddressOf LongRunningInitialization2)
    Dim thread3 As New Threading.Thread(AddressOf LongRunningInitialization3)
    Dim thread4 As New Threading.Thread(AddressOf LongRunningInitialization4)
    Dim thread5 As New Threading.Thread(AddressOf LongRunningInitialization5)
    Dim thread6 As New Threading.Thread(AddressOf LongRunningInitialization6)
    Dim thread7 As New Threading.Thread(AddressOf LongRunningInitialization7)
    thread1.Join()
    thread2.Join()
    thread3.Join()
    thread4.Join()
    thread5.Join()
    thread6.Join()
    thread7.Join()
End Sub

虽然这个简陋的作品,Join()是一个阻塞调用,并在其中thread1最花费时间的一个screnario,其它线程是“植物大战僵尸”,只要thread1完成。还没有在这里实现闪屏,进度条冻结为Join()是一个阻塞调用。

我想出了另一种“解决方案”通过使用一个线程的while and theThreadState`物业办无阻塞等待在哈克的方式:

Friend Sub Main()
    Dim thread1 As New Threading.Thread(AddressOf LongRunningInitialization1)
    Dim thread2 As New Threading.Thread(AddressOf LongRunningInitialization2)
    Dim thread3 As New Threading.Thread(AddressOf LongRunningInitialization3)
    Dim thread4 As New Threading.Thread(AddressOf LongRunningInitialization4)
    Dim thread5 As New Threading.Thread(AddressOf LongRunningInitialization5)
    Dim thread6 As New Threading.Thread(AddressOf LongRunningInitialization6)
    Dim thread7 As New Threading.Thread(AddressOf LongRunningInitialization7)
    While thread1.ThreadState = Threading.ThreadState.Running _
        OrElse thread2.ThreadState = Threading.ThreadState.Running _
        OrElse thread3.ThreadState = Threading.ThreadState.Running _
        OrElse thread4.ThreadState = Threading.ThreadState.Running _
        OrElse thread5.ThreadState = Threading.ThreadState.Running _
        OrElse thread6.ThreadState = Threading.ThreadState.Running _
        OrElse thread7.ThreadState = Threading.ThreadState.Running
        Application.DoEvents() ' process the Windows Forms message queue.
        Threading.Thread.Sleep(1) ' non-blocking wait.
    End While
    thread1.Join()
    thread2.Join()
    thread3.Join()
    thread4.Join()
    thread5.Join()
    thread6.Join()
    thread7.Join()
End Sub

虽然这最后落实在这个例子中工作,当你应该并行大多奔波20长期运行初始化任务所面临的现实世界中,无法使用。该while条件的尺寸就达到史诗。

是否有执行非阻塞等待它在那里创建的所有线程的解决方案?类似下面的伪代码:

Friend Sub Main()
    Dim threadPool As New PseudoThreadPool()
    threadPool.Add(New Threading.Thread(AddressOf LongRunningInitialization1))
    threadPool.Add(New Threading.Thread(AddressOf LongRunningInitialization2))
    threadPool.Add(New Threading.Thread(AddressOf LongRunningInitialization3))
    threadPool.Add(New Threading.Thread(AddressOf LongRunningInitialization4))
    threadPool.Add(New Threading.Thread(AddressOf LongRunningInitialization5))
    threadPool.Add(New Threading.Thread(AddressOf LongRunningInitialization6))
    threadPool.Add(New Threading.Thread(AddressOf LongRunningInitialization7))
    threadPool.Start()
    While threadPool.AllDone = False
        Application.DoEvents() ' process the Windows Forms message queue.
        Threading.Thread.Sleep(1) ' non-blocking wait.
    End While
    threadPool.Join()
End Sub
.net vb.net multithreading
1个回答
1
投票

我已经找到了解决,这要归功于@Jimi(List(Of Task)方法)。

Friend Sub Main()
    Dim tasks As New List(Of Task)
    tasks.Add(New Task(AddressOf LongRunningInitialization1))
    tasks.Add(New Task(AddressOf LongRunningInitialization2))
    tasks.Add(New Task(AddressOf LongRunningInitialization3))
    tasks.Add(New Task(AddressOf LongRunningInitialization4))
    tasks.Add(New Task(AddressOf LongRunningInitialization5))
    tasks.Add(New Task(AddressOf LongRunningInitialization6))
    tasks.Add(New Task(AddressOf LongRunningInitialization7))
    ' Start all tasks.
    tasks.All(
        Function(t As Task)
            t.Start()
            Return True
        End Function
    )
    ' Wait until all tasks has been finished.
    While tasks.Any(Function(t As Task) Not (t.Status = TaskStatus.Canceled OrElse t.Status = TaskStatus.Faulted OrElse t.Status = TaskStatus.RanToCompletion))
        Application.DoEvents()
        Sleep(1)
    End While
End Sub
© www.soinside.com 2019 - 2024. All rights reserved.