我有一个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 the
ThreadState`物业办无阻塞等待在哈克的方式:
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
我已经找到了解决,这要归功于@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