我有一个使用Visual Basic的MultiThreading问题和概念性问题(但它几乎适用于所有语言)。 我有一个功能:
如何确保班级的所有实例都有机会在主要切断之前完成?
通过研究提供最相关的帮助:How do I pause main() until all other threads have died?
这是我的代码:
Imports System
Imports System.Threading
Imports System.Collections.Generic
Module Module1
Private raceTrack As New List(Of RaceCar)
Sub Main()
CreateRace()
'Main() would quit when the 5 car objects are created =[
'How do I make sure Main will not exit until all racecars are done?
End Sub
Sub CreateRace()
For index As Integer = 1 to 5
raceTrack.Add(new RaceCar(index))
Next
End Sub
Public Class RaceCar
Private testThread as Thread = New Thread(AddressOf StartEngine)
Private carId as Integer
Public Sub New(ByVal carNumber as Integer)
me.carId = carNumber
Me.TestThread.Start()
Me.TestThread.Join()
End Sub
Public Sub StartEngine()
Console.WriteLine(String.Format("Car#{0} is going!", Me.carId))
Thread.Sleep(100*Me.carId)
Console.WriteLine(String.Format("Car#{0} is DONE!", Me.carId))
End Sub
End Class
End Module
答案 0 :(得分:1)
显然,您的RaceCar
构造函数仅在生成的线程完成时返回,因为您正在调用Join
。
Public Sub New(ByVal carNumber as Integer)
me.carId = carNumber
Me.TestThread.Start()
Me.TestThread.Join()
End Sub
我不知道这是否是故意的(很可能不是,因为你是在循环中创建RaceCar
个实例,所以你没有并行性,因为在前一个构造函数调用之前无法创建下一个实例返回),但绝对你的主线程无法完成,直到所有子线程都完成。
我建议进行以下重组:
从构造函数中移除Join
并在RaceCar
类中添加新方法:
Public Sub JoinThread()
Me.TestThread.Join()
End Sub
现在对象创建循环不会阻塞。之后再添加一个循环:
Sub CreateRace()
For index As Integer = 1 to 5
raceTrack.Add(new RaceCar(index))
Next
// other work maybe?
For Each car As RaceCar In raceTrack
car.JoinThread()
Next
End Sub
现在你的线程将在第一个循环中开始,并行运行它们的工作并最终停止在新的“屏障循环”上。
请注意,主线程仍然可以在两个循环之间执行其他任务。
(免责声明:我从未在vb.net中编程,所以希望我写的并不完全错误。)
答案 1 :(得分:0)
我不确定我是否遗漏了某些东西(我打赌这是一个示例项目),但我无法重现这个问题。当我运行您发布的代码时,我可以看到所有车辆进入(减去都铎提到的.Join呼叫)。
但是,如果我将Thread.IsBackground
设置为True
,然后,我会看到您的问题。为了确保Thread
在Process
终止之前完成,请执行以下操作:
Public Sub New(ByVal carNumber As Integer)
Me.carId = carNumber
Me.testThread.IsBackground = False ' <--This will cause threads to be 'Foreground'
Me.testThread.Start()
End Sub
查看Thread.IsBackground
:http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground(v=vs.95).aspx
此属性会告诉您Process
是否会在终止前等待Thread
完成。显然,在您的情况下,您希望这是False
。在许多情况下,它默认为False
,但有时可能会将其设置为true。