vinduer - hvordan man sikrer forekomster af klasse færdig inden hovedet afslutter?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har et MultiThreading problem og konceptuelle spørgsmål ved hjælp af Visual Basic (men det gælder næsten alle sprog).
Jeg har en funktion som:



  1. opretter 5 tilfælde af en klasse, som hver springer en tråd, der kalder en funktion

  2. Funktionen sover i X milli-sekunder

  3. udskriver til konsol

  4. Afslutter derefter tråden



Hvordan kan jeg sikre, at alle forekomster af klassen får en chance for at afslutte før hovedafbrydelser er slukket?


Mest relevant hjælp gennem forskning: Hvordan holder jeg pause i hovedmenuen (), indtil alle andre tråde er døde?


Her er min kode:



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

Bedste reference


Tilsyneladende vender din RaceCar konstruktør kun tilbage, når den genstøbte tråd er færdig, siden du ringer Join.


    Public Sub New(ByVal carNumber as Integer)
        me.carId = carNumber
        Me.TestThread.Start()
        Me.TestThread.Join()
    End Sub


Jeg ved ikke, om dette er forsætligt (sandsynligvis ikke fordi du skaber dine RaceCar tilfælde i en loop, så du ikke har nogen parallelisme, da næste instans ikke kan oprettes, før det tidligere konstruktøropkald returneres) men helt sikkert kan din hovedtråd ikke afslutte, før alle barnets tråde er færdige.


Jeg foreslår følgende omstrukturering:


Fjern Join fra konstruktøren og tilføj en ny metode i din RaceCar klasse:


Public Sub JoinThread()
    Me.TestThread.Join()
End Sub


Nu blokerer objektets oprettelsessløjfe ikke. Tilføj en anden sløjfe bagefter:


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


Nu starter dine tråde i den første loop, løber deres arbejde parallelt og til sidst stopper på den nye 'barriereløkke'.


Bemærk, at hovedtråden stadig kan udføre andre opgaver mellem de to løkker.


(Ansvarsfraskrivelse: Jeg har aldrig programmeret i vb.net, så forhåbentlig det jeg skrev er ikke helt forkert.)

Andre referencer 1


Jeg er ikke sikker på, om jeg mangler noget (jeg vedder på, at dette er et prøveprojekt), men jeg kan ikke reproducere problemet. Jeg kan se alle de biler, der kommer ind, når jeg kører koden du skrev op (minus .Join call som nævnt af Tudor).


Men hvis jeg sætter Thread.IsBackground til True, så ser jeg dit problem. For at sikre, at dine Thread s er færdige, inden Process afslutter, skal du gøre dette:


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


Se nærmere på definitionen af ​​Thread.IsBackground: http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground(v=vs.95).aspx[21]


Denne egenskab fortæller dig, om Process vil vente på, at Thread skal afslutte før afslutningen. Naturligvis i dit tilfælde, vil du have dette til at være False. Det er i mange tilfælde tilfældet False, men der kan være tilfælde, hvor det sættes til sandt.