Moin,
ich tueftel gerade nen bisschen an nem Tool rum, eine Aufgabe ist es 2 Timer (basierend auf einer Klasse) am Laufen zu halten, diese beiden Timer sind voneinander abhaengig in der Aktion die nach ablaufen der Periode ausgeführt wird - zwingend.
Vorab die Klassen:
Beide Timer werden im Hauptthread in den Applicationevents gestartet und in diesem Modul behandelt:
Nun ist mein Problem das die Events der Threads ja in sich selber abgefangen werden und nicht im Hauptthread, dadurch werden die Zaehler angehalten und neugestartet im subthread, welche nach dem starten aber wie gewollt fertig ist und somit steht. Ich suche nun einen Weg zu verhindern das eine Aktion durch einen der Timer ausgefuehrt wird solange der andere Timerthread aktiv ist und danach moechte ich den Timer im Hauptthread neustarten (swapEventTimer(true)) und danach _muessen_ aber die aktionen im anderen Thread sofern welche angefallen sind abgearbeitet werden - das klappt ja soweit schon, nur kann ich den timer im Hauptthread nicht neustarten, da ich ja ohne irgendwas nicht weiss ob der Timer nun durch ist _und_ die aktionen fertig sind.
Es Hilft leider auch nichts die Aktionen direkt in die Events des Timers zu packen - zumindest mir nicht - da ich nicht wuesste wie ich dort sicherstellen kann das die Aktion von timer 2 erst ausgefuehrt wird wenn timer 1 beendet ist oder nicht verloren geht...
Ich zerbrech mir seit geschlagenen 2 Tagen die Birne und kenn die google Suchergebnise zu Threads auswendig, desweiteren habe ich ein wenig mit delegate gespielt - ohne erfolg, seitdem ich die threads nutze ist mir sogar eher funktion verloren gegangen (der draw auf die progressbar funktioniert nicht mehr).
Waere super wenn jemand eine Idee haette wie man das loesen kann - am besten bitte mit kurzem Beispiel
ich tueftel gerade nen bisschen an nem Tool rum, eine Aufgabe ist es 2 Timer (basierend auf einer Klasse) am Laufen zu halten, diese beiden Timer sind voneinander abhaengig in der Aktion die nach ablaufen der Periode ausgeführt wird - zwingend.
Vorab die Klassen:
VB.NET-Quellcode
- Public Class clsTimer
- ' Timer
- Private WithEvents _eventTimer As New Timer
- ' Variables
- Private eventTimerTicks As Double = 1
- Private eventTimerNeeded As Double = 0
- Private eventTimerName As String = Nothing
- Private eventTimerMinutes As String = "0"
- Private eventProgressBar As ProgressBar
- Private timeMax As String = Nothing
- Private timeDone As String = Nothing
- ' Events
- Public Event startedTimer()
- Public Event stoppedTimer()
- Public Event doneTick(ByVal tName As String, ByVal cntTicks As Double)
- Public Event reachedTicks(ByVal tName As String, ByVal cntTicks As Double)
- Public Sub New(Optional ByVal tName As String = Nothing, Optional ByRef tProgress As ProgressBar = Nothing, Optional ByVal allTime As Double = 0)
- _eventTimer.Enabled = False
- _eventTimer.Interval = 1000
- eventTimerNeeded = allTime * 60
- eventTimerName = tName
- eventProgressBar = tProgress
- resetProgress()
- timeMax = GetMins(CInt(allTime))
- End Sub
- Public Sub eventTimerSwap(Optional ByVal doReset As Boolean = False)
- If doReset Then
- resetProgress()
- eventTimerTicks = 1
- End If
- _eventTimer.Enabled = Not _eventTimer.Enabled
- If _eventTimer.Enabled Then
- RaiseEvent startedTimer()
- Debug.WriteLine(eventTimerName + ": start" + workingAction)
- Else
- RaiseEvent stoppedTimer()
- Debug.WriteLine(eventTimerName + ": stop" + workingAction)
- End If
- End Sub
- Private Sub eventTimerTick(ByVal sender As Object, ByVal e As System.EventArgs) Handles _eventTimer.Tick
- textToProgress(CStr(eventTimerTicks))
- If eventTimerTicks = eventTimerNeeded Then
- If eventProgressBar.Visible Then eventProgressBar.Value = eventProgressBar.Maximum
- eventTimerSwap(True)
- RaiseEvent reachedTicks(eventTimerName, eventTimerNeeded)
- Else
- If eventProgressBar.Visible Then eventProgressBar.Value = CInt(eventTimerTicks)
- RaiseEvent doneTick(eventTimerName, eventTimerTicks)
- eventTimerTicks += 1
- End If
- End Sub
- Private Sub textToProgress(ByVal writeString As String)
- Dim canvas As Graphics = eventProgressBar.CreateGraphics
- Dim cFont As New Font("Dina", 8, FontStyle.Regular)
- Dim cFontLength As SizeF = canvas.MeasureString(writeString, cFont)
- Dim pSize As SizeF
- pSize.Width = eventProgressBar.Width
- pSize.Height = eventProgressBar.Height
- canvas.DrawString(writeString, cFont, New SolidBrush(Color.Black), New PointF(pSize.Width / 2 - (cFontLength.Width / 2.0F), pSize.Height / 2 - (cFontLength.Height / 2.0F)))
- canvas.Dispose()
- End Sub
- Private Sub resetProgress()
- eventProgressBar.Maximum = CInt(eventTimerNeeded)
- eventProgressBar.Minimum = 0
- eventProgressBar.Value = 0
- Application.DoEvents()
- End If
- End Sub
- Private Function GetMins(ByVal vSeconds As Integer) As String
- Dim min, sec As String
- min = CStr(Math.DivRem(vSeconds, 60, vSeconds))
- sec = CStr(vSeconds Mod 60)
- Return min & ":" & sec
- End Function
- End Class
- Public Class threadingObject
- Shared lockerObject As Object = New Object()
- Public Event threadDone(ByVal threadName As String)
- Public Sub threadingLoop()
- threadRunning = True
- SyncLock lockerObject
- ' action
- workingAction = Nothing
- End SyncLock
- threadRunning = False
- RaiseEvent threadDone("threadingLoop")
- End Sub
- Public Sub reloadLoop()
- threadRunning = True
- SyncLock lockerObject
- ' action
- workingAction = Nothing
- End SyncLock
- threadRunning = False
- RaiseEvent threadDone("reloadLoop")
- End Sub
- End Class
Beide Timer werden im Hauptthread in den Applicationevents gestartet und in diesem Modul behandelt:
VB.NET-Quellcode
- Module modTimerEvents
- Public WithEvents eTimerH As New clsTimer("t1", frmMain.pNext, 0.3)
- Public WithEvents eTimerR As New clsTimer("t2", frmMain.pReload, 0.2)
- Public WithEvents threadingObject As New threadingObject
- Public workingWithMouse As String = Nothing, workingAction As String = Nothing
- Private Sub doActions(ByVal tName As String, ByVal cntTicks As Double) Handles eTimerH.reachedTicks
- workingAction = "actions"
- Dim tActions As New Thread(AddressOf threadingObject.threadingLoop)
- tActions.Start()
- End Sub
- Private Sub doReload(ByVal tName As String, ByVal cntTicks As Double) Handles eTimerR.reachedTicks
- workingAction = "reload"
- Dim tActions As New Thread(AddressOf threadingObject.reloadLoop)
- tActions.Start()
- End Sub
- Private Sub threadingObject_threadDone(ByVal threadName As String) Handles threadingObject.threadDone
- If threadName = "reloadLoop" Then
- eTimerR.eventTimerSwap(True)
- Else
- eTimerH.eventTimerSwap(True)
- End If
- End Sub
- End Module
Nun ist mein Problem das die Events der Threads ja in sich selber abgefangen werden und nicht im Hauptthread, dadurch werden die Zaehler angehalten und neugestartet im subthread, welche nach dem starten aber wie gewollt fertig ist und somit steht. Ich suche nun einen Weg zu verhindern das eine Aktion durch einen der Timer ausgefuehrt wird solange der andere Timerthread aktiv ist und danach moechte ich den Timer im Hauptthread neustarten (swapEventTimer(true)) und danach _muessen_ aber die aktionen im anderen Thread sofern welche angefallen sind abgearbeitet werden - das klappt ja soweit schon, nur kann ich den timer im Hauptthread nicht neustarten, da ich ja ohne irgendwas nicht weiss ob der Timer nun durch ist _und_ die aktionen fertig sind.
Es Hilft leider auch nichts die Aktionen direkt in die Events des Timers zu packen - zumindest mir nicht - da ich nicht wuesste wie ich dort sicherstellen kann das die Aktion von timer 2 erst ausgefuehrt wird wenn timer 1 beendet ist oder nicht verloren geht...
Ich zerbrech mir seit geschlagenen 2 Tagen die Birne und kenn die google Suchergebnise zu Threads auswendig, desweiteren habe ich ein wenig mit delegate gespielt - ohne erfolg, seitdem ich die threads nutze ist mir sogar eher funktion verloren gegangen (der draw auf die progressbar funktioniert nicht mehr).
Waere super wenn jemand eine Idee haette wie man das loesen kann - am besten bitte mit kurzem Beispiel
sfmStatus @konzeption: 2%