SyncLock来自两个不同线程的相同对象

时间:2013-10-17 08:55:46

标签: vb.net synclock

基本上我有一个全局变量,例如......

Dim int1 as integer

然后我有两个异步函数,比如......

function bleh()
    int1 += 1
end function

function Meh()
     int1 -= 1
end function

这两个函数都由Task.Run()运行。

我想在这两个功能中使用SyncLock。但是,MSDN站点上给出的所有示例仅显示在单个函数中使用的SyncLock的示例。所以我不能简单地从MSDN描述中说出,对于我来说,在全局变量上跨两个不同的函数使用SyncLock是“没问题的”。

我想做的是这样的事情:

Private Shared SyncObj as Object '<-- global
Dim int1 as integer '<-- global

Sub Form_Load(...)
     SyncObj = new Object
     Task.Run(Function() bleh())
     Task.Run(Function() Meh())
End Sub

Function bleh()
     SyncLock SyncObj
        int1 += 1
     End SyncLock
End Function
Function Meh()
     SyncLock SyncObj
        int1 -= 1
     End SyncLock
End Function

这可以吗?将bleh()阻止Meh()改变int1,反之亦然?谢谢!对不起VB lol。

1 个答案:

答案 0 :(得分:5)

是的,没关系。 SyncLock就是为此而设计的。当其他线程正在使用它时,它避免了其他线程访问资源。我建议你做一个Console.Writeline或Debug.Writeline来跟随它的输出。

添加一个While,以检查值的变化方式:

Sub Form_Load(...)
     SyncObj = new Object
     While true
      Task.Run(Function() bleh())
      Task.Run(Function() Meh())
     End while     
End Sub

Function bleh()
     SyncLock SyncObj
        int1 += 1
        Debug.Writeline("from thread bleh: " & int1.toString)
     End SyncLock
End Function
Function Meh()
     SyncLock SyncObj
        int1 -= 1
         Debug.Writeline("from thread meh: " & int1.toString)
     End SyncLock
End Function

Synclock 会阻止bleh()访问该代码,而meh()正在使用它,反之亦然。

编辑:我执行了你的代码,这是输出:

  

来自线程meh:-1

     

来自线程meh:-2

     

来自线程bleh:-1

     

来自线程bleh:0

     

from thread bleh:1

     

来自线程meh:0

     

from thread bleh:1

     

来自线程meh:0

     

from thread bleh:1

     

来自线程meh:0

     

来自线程meh:-1

     

来自线程bleh:0

     

from thread bleh:1

     

来自线程meh:0

     

from thread bleh:1

     

from thread bleh:2

     

来自线程meh:1

     

来自线程meh:0

     

来自线程meh:-1

     

来自线程bleh:0

您阻止访问 int1 ,但是您无法控制一个线程在另一个线程被触发之前执行两次,如您所见。

使用另一个示例,,例如使用文件,这可能很有用。它不能一次从两个线程接收,否则会产生异常。

这里有例子:

 Imports System.Threading.Tasks
Imports System.IO

Module Module2

    Dim SyncObj As Object

    Dim path As String = "c:\testfile.text"
    Sub Main()

        SyncObj = New Object
        While True
            Task.Factory.StartNew(Function() bleh())
            Task.Factory.StartNew(Function() Meh())
        End While
    End Sub

    Function bleh()
        SyncLock SyncObj

            Using sw As New StreamWriter(path, True)
                sw.WriteLine("From bleh!!!")
            End Using
        End SyncLock
    End Function
    Function Meh()
        SyncLock SyncObj
            Using sw As New StreamWriter(path, True)
                sw.WriteLine("From meh!!!")
            End Using
        End SyncLock
    End Function

End Module

此示例在路径文件上写了 26814行,在几秒钟内没有任何异常,因此没有发生对资源的并发访问。