2012-02-14 73 views
0

我有一個使用Visual Basic的多線程問題和概念問題(但它幾乎適用於所有語言)。 我有一個函數:如何確保主要終止之前完成課程的實例?

  1. 創建類的5個實例,其中每個派生它調用一個功能
  2. 的作用休眠X毫秒的螺紋
  3. 打印到控制檯
  4. 然後終止線程

如何確保班級的所有實例都有機會在主要切斷之前完成?通過研究

最相關的幫助: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

您可以在您的實例化的每個類的調用程序中增加一個「counter」,並在每個類的線程終止時爲每個類引發一個「Event」。然後在你的調用程序中創建一個''EventHandler'來減少'counter'。當counter = 0時,所有的線程都被終止。 – 2012-02-14 20:41:07

+0

@Michael這聽起來不錯,我會試試看。 – Ken 2012-02-14 20:48:37

+0

都鐸王朝的回答對你代碼中的缺陷有一個好的看法。 – 2012-02-14 20:50:33

回答

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編程,所以希望我寫的是不是完全錯誤的。)

+0

這是否意味着當StartEngine()完成時,線程將自動終止?我之後做了Join(),因爲1)我見過的其他例子(例如research鏈接)有一個類似的東西,線程被創建,然後立即再次加入。和2)我以爲我不得不終止線程 – Ken 2012-02-14 20:53:28

+1

是的,確切地說,一個線程終止時,它應該執行的方法返回。 – Tudor 2012-02-14 20:55:39

0

我不知道如果我失去了一些東西(我敢打賭,這是一個樣本項目),但我不能重現問題。當我運行您發佈的代碼時,我可以看到所有進入的汽車(減去都鐸提到的.Join調用)。

但是,如果我設置Thread.IsBackgroundTrue,然後我看到您的問題。爲了確保您的Thread s的在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。

相關問題