J'ai cette situation: un formulaire avec un System.Timer dedans (avec AutoReset = False). La forme a son fil principal et le minuteur son propre fil aussi (rien de nouveau ici). Lorsque l'utilisateur appuie sur un bouton, je dois arrêter la minuterie, attendre que le thread du minuteur ait arrêté son exécution et faire quelque chose de plus. De l'autre côté, la minuterie met à jour un élément dans le formulaire afin BeginInvoke est utilisé. Le code ressemble à ceci:Comment gérer cette situation Multithread et ne pas verrouiller?
Code Button:
Private Sub ButtonStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonStop.Click
SyncLock (m_stopLock)
m_stopProcessTimer = True
Threading.Monitor.Wait(m_stopLock)
End SyncLock
''#Do more things here after the timer has end its execution and is stopped
End Sub
Code Timer:
Private Sub m_processTimer_Elapsed(ByVal sender As Object, ByVal e As System.EventArgs) Handles m_processTimer.Elapsed
Dim auxDelegate As EventHandler
SyncLock (m_stopLock)
If Not m_stopProcessTimer Then
If Me.InvokeRequired Then
auxDelegate = New EventHandler(AddressOf m_processTimer_Elapsed)
Me.BeginInvoke(auxDelegate, New Object() {sender, e})
Else
DoFormStuf()
m_processTimer.Start()
End If
Else
Threading.Monitor.Pulse(m_stopLock)
End If
End SyncLock
End Sub
Le point est que j'attends le fil conducteur de laisser le fil de la minuterie pour terminer son travail.
Le problème est que ce code se bloque lorsque l'utilisateur clique sur le bouton lorsque le BeginInvoke va être appelé. Comment une chose aussi simple que celle-ci peut-elle être faite? On dirait que je ne peux pas trouver une bonne solution à ce problème :(
Désolé, j'ai mis à jour le gestionnaire de boutons pour montrer que je dois attendre que l'exécution de la minuterie se termine et qu'elle soit arrêtée (elle ne s'exécute plus) et après que quelque chose soit fait. –
Ne pas "attendre", il suffit que l'interface utilisateur ne fasse rien, et que le chronométreur déclenche l'élément du répartiteur pour terminer le reste. Vous ne pouvez pas bloquer dans un thread d'interface utilisateur de toute façon, sinon l'interface utilisateur va se bloquer. –
Ok, maintenant je vois ce que vous voulez dire. C'est une sorte de rappel appelé du code temporisateur n'est-ce pas? –