如何处理这种多线程情况并且不锁定?

时间:2009-11-25 17:38:24

标签: vb.net multithreading deadlock

我遇到这种情况:一个带有System.Timer的表单(AutoReset = False)。表单的主线程和计时器也是自己的线程(这里没什么新东西)。

当用户按下按钮时我需要停止计时器,等到计时器线程停止执行并再做一些事情。

另一方面,计时器更新表单中的项目,以便使用BeginInvoke。代码如下所示:

按钮代码:

 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

计时器代码:

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

重点是我等待主线程让计时器线程结束其工作。

问题是当用户在要调用BeginInvoke时单击按钮时,此代码会死锁。怎么这样的简单事情可以做到?看起来我找不到解决这个问题的好方法:(

2 个答案:

答案 0 :(得分:2)

根本不要使用锁,只需确保在UI线程上执行所有操作,并且可以保证不会损坏任何内容。请记住,调度程序项在UI线程上运行,因此您知道如果您在调度程序项或事件处理程序中执行所有操作,则只执行一个事项一段时间。

答案 1 :(得分:0)

1)也许更多的代码会有所帮助。你是否创建了一个新线程并将计时器置于该线程上?

2)您是否尝试过使用ManualResetEvent(.WaitOne()和.Set()?)

3)在您的活动中,如果需要调用,您将再次重新调用您的活动。混乱...

4)你应该等到另一个线程完成吗?那么Thread.Join()?