Josef Morlo
2011-02-24 12:45:55 UTC
Hallo,
Ich habe zwei Fragen zu Threads, zu Join und ManualResetEvent im
besonderen.
Ein (Übungs-)Programm mit folgender Struktur: Mehrere Threads mit jeweils
Threadprozedur. Darin jeweils eine Schleife, StopFlag und Rückruf.
Schematisch:
Public Class Form1
Private mThread1 as Thread
…
Private mThreadN as Thread
Private mStopFlag as Boolean
Private mThreadCounter as Integer
Private Delegate Sub DelClosingForm()
Sub ThreadProc1()
While not mStopFlag
SyncLock(me)
'Tut was mit Zählern und Aktualisierung von Steuerelementen
End SyncLock
End While
'Rückmeldung, wenn Schleifendurchlauf beendet
Invoke(New DelClosingForm(AddressOf CloseForm))
End Sub
Analog die weiteren Thread-Prozeduren
Private Sub btnStart_Click(…)
mThread1 = New Thread(New ThreadStart(AddressOf ThreadProc1))
mThread1.Start()
mThreadCounter +=1
…
mThreadN = New Thread(New ThreadStart(AddressOf ThreadProcN))
mThreadN.Start()
mThreadCounter +=1
Form schließen
Private Sub btnExit_Click(…)
Me.Close()
End Sub
Private Sub Form1_FormClosing(…)
If mThreadCounter <> 0 Then
mStopFlag = True
e.Cancel = True
End If
'Alternativ zu CloseForm und Delegate:
'mStopFlag = True
'Do Until mThreadCounter = 0
'Application.DoEvents()
'Loop
End Sub
Sub CloseForm()
'Rückmeldung aller Threads abpassen
mThreadCounter -= 1
If mThreadCounter = 0 Then
Me.Close()
End If
End Sub
End Class
Das funktioniert auch soweit, Schleifendurchläufe und Threads werden
ordnungsgemäß beendet.
Erste Frage:
Ist es im konkreten Fall zwingend notwendig, In- und Dekrementierung des
Threadzählers abzusperren, also etwa so:
mThreadCounter = Max(Interlocked.Increment(mThreadCounter), _
(mThreadCounter - 1)) ?
Zweite Frage:
Wenn ich die Threadkonzepte recht verstanden habe, so müsste sich doch auch
die Möglichkeit bieten, den Haupthread warten zu lassen (Join) bzw. ein
Signal zu setzen (ManualResetEvent), bis bzw. wenn die Nebenthreads den
Schleifendurchgang abgeschlossen haben. Ich finde keinen Ansatzpunkt. Wie
müsste man das einbauen?
Danke für Ideen
Grüße
Josef Morlo
Ich habe zwei Fragen zu Threads, zu Join und ManualResetEvent im
besonderen.
Ein (Übungs-)Programm mit folgender Struktur: Mehrere Threads mit jeweils
Threadprozedur. Darin jeweils eine Schleife, StopFlag und Rückruf.
Schematisch:
Public Class Form1
Private mThread1 as Thread
…
Private mThreadN as Thread
Private mStopFlag as Boolean
Private mThreadCounter as Integer
Private Delegate Sub DelClosingForm()
Sub ThreadProc1()
While not mStopFlag
SyncLock(me)
'Tut was mit Zählern und Aktualisierung von Steuerelementen
End SyncLock
End While
'Rückmeldung, wenn Schleifendurchlauf beendet
Invoke(New DelClosingForm(AddressOf CloseForm))
End Sub
Analog die weiteren Thread-Prozeduren
Private Sub btnStart_Click(…)
mThread1 = New Thread(New ThreadStart(AddressOf ThreadProc1))
mThread1.Start()
mThreadCounter +=1
…
mThreadN = New Thread(New ThreadStart(AddressOf ThreadProcN))
mThreadN.Start()
mThreadCounter +=1
Form schließen
Private Sub btnExit_Click(…)
Me.Close()
End Sub
Private Sub Form1_FormClosing(…)
If mThreadCounter <> 0 Then
mStopFlag = True
e.Cancel = True
End If
'Alternativ zu CloseForm und Delegate:
'mStopFlag = True
'Do Until mThreadCounter = 0
'Application.DoEvents()
'Loop
End Sub
Sub CloseForm()
'Rückmeldung aller Threads abpassen
mThreadCounter -= 1
If mThreadCounter = 0 Then
Me.Close()
End If
End Sub
End Class
Das funktioniert auch soweit, Schleifendurchläufe und Threads werden
ordnungsgemäß beendet.
Erste Frage:
Ist es im konkreten Fall zwingend notwendig, In- und Dekrementierung des
Threadzählers abzusperren, also etwa so:
mThreadCounter = Max(Interlocked.Increment(mThreadCounter), _
(mThreadCounter - 1)) ?
Zweite Frage:
Wenn ich die Threadkonzepte recht verstanden habe, so müsste sich doch auch
die Möglichkeit bieten, den Haupthread warten zu lassen (Join) bzw. ein
Signal zu setzen (ManualResetEvent), bis bzw. wenn die Nebenthreads den
Schleifendurchgang abgeschlossen haben. Ich finde keinen Ansatzpunkt. Wie
müsste man das einbauen?
Danke für Ideen
Grüße
Josef Morlo