wanren2008 发表于 2011-7-8 20:32:34

请教下数据同步的问题

我用VB2005,多线程运行同一任务,但是会存取主线程(窗体)中的数据,因此要加锁。

可是,Monitor.Enter虽然不同线程互斥,但是同一线程却可以多次锁定,而我希望不管是不是同一线程,同一时刻只希望锁定一次。想来想去,就做了个类,类里边开启线程来锁定对象,这样在主程序中每次锁定都是在不同的线程。
但是测试了下,发现没有效果。

不知道什么原因?或者有什么别的好办法?

-----------------------------------------------
主程序:
Dim objLock as New Object

使用时,在子程序中:
Dim myLock as New MyMonit()
myLock.Enter(objLock)
...
myLock.Exit()

------------------------------------------------
我写的类:
   Public Class MyMonit
      Dim Locked As Boolean = False
      Dim WithEvents bgw As New System.ComponentModel.BackgroundWorker()

      Public Sub Enter(ByVal objLock As Object)
            Locked = True
            bgw.RunWorkerAsync(objLock)
      End Sub

      Public Sub ()
            Locked = False
      End Sub

      Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
            System.Threading.Monitor.Enter(e.Argument)
            Do While Locked
                System.Threading.Thread.Sleep(1)
                Application.DoEvents()
            Loop
            System.Threading.Monitor.Exit(e.Argument)
      End Sub
    End Class

wanren2008 发表于 2011-7-9 08:32:09

自己发现问题了:
在自己的类中,锁定时阻止了自己,但是因为不是在主程序中锁定,所以主程序继续下一句了。

改成下边了,但是发现在主程序中,如果上一个锁定的代码还在执行,在另一个地方锁定的话,
就陷入第2次锁定的死循环中了。
不知道有什么好办法没有?

------------------------------------------------
Public Class MyMonit
    Dim Locked As Boolean = False
    Dim flg As String = "---"
    Dim WithEvents bgw As New System.ComponentModel.BackgroundWorker()

    Public Sub New(ByVal objLock As Object, ByVal flg As String)
      Me.flg = flg
      bgw.RunWorkerAsync(objLock)
    End Sub

    Public Sub WaitUntilLocked()
      Do Until Locked
            System.Threading.Thread.Sleep(10)
            Application.DoEvents()
            'Debug.Print("Wait Locked " & flg & ", " & Now)
      Loop
    End Sub

    Public Sub ()
      Locked = False
    End Sub

    Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
      System.Threading.Monitor.Enter(e.Argument)
      Locked = True
      Debug.Print("Locked " & Now)
      Do While Locked
            System.Threading.Thread.Sleep(1)
            Application.DoEvents()
      Loop
      System.Threading.Monitor.Exit(e.Argument)
    End Sub

    Private Sub bgw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted
      Me.bgw.Dispose()
    End Sub

End Class
页: [1]
查看完整版本: 请教下数据同步的问题