I have this situation: a Form with a System.Timer in it (with AutoReset = False). The form has its main thread and the timer its own thread too (nothing new here).
When the user press a button I need to stop the timer, wait until the timer thread has stopped its execution and do something more.
On the other side, the timer updates an item at the form so BeginInvoke is used. The code looks like this:
Button Code:
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
Timer code:
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
The point is that I wait the main thread to let the timer thread to end its work.
The problem is that this code deadlocks when the user clicks the button when the BeginInvoke is going to be called. How a simple thing like this one can be done? Looks like I cannot find a good solution to this problem :(