vb.net SyncLock 来自两个不同线程的同一个对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19422189/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 15:30:31  来源:igfitidea点击:

SyncLock the same object from two different threads

vb.netsynclock

提问by Aaron Brown

Basically I have a global variable, such as...

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

Dim int1 as integer

And then I have two asynchronous functions, such as...

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

function bleh()
    int1 += 1
end function

and

function Meh()
     int1 -= 1
end function

Both these functions are being run by Task.Run().

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

I want to use SyncLock in both these functions. However, all the examples given on the MSDN site only show examples of SyncLock being used within a single function. So I can't tell simply from the MSDN description if it is "okay" for me to use SyncLock across two different functions, on a global variable.

我想在这两个函数中使用 SyncLock。但是,MSDN 站点上给出的所有示例仅显示了在单个函数中使用的 SyncLock 示例。因此,我无法简单地从 MSDN 描述中判断在全局变量上跨两个不同的函数使用 SyncLock 是否“可以”。

What I want to do is something like this:

我想做的是这样的:

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

Is this okay to do? Will bleh() block Meh() from changing int1, and vise versa? Thanks! Sorry for the VB lol.

这样做可以吗?bleh() 会阻止 Meh() 更改 int1,反之亦然吗?谢谢!对不起 VB 大声笑。

回答by Carlos Landeras

Yeah It is OK. SyncLockis designed for that. It avoids other thread accessing to a resource while other thread is working with it. I recommend you to do a Console.Writeline or Debug.Writeline to follow its output.

是的 没关系。SyncLock是为此而设计的。它避免了其他线程在其他线程正在使用资源时访问资源。我建议您执行 Console.Writeline 或 Debug.Writeline 以跟踪其输出。

Add a While true to check how the values are changing:

添加一个 While true 来检查值是如何变化的:

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

The Synclock, will prevent bleh() to access that code while meh() is working with it, and viceversa.

SYNCLOCK,将阻止的Bleh()来访问代码,而MEH()正在与它,反之亦然。

EDIT: I executed your code and this is the output:

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

from thread meh: -1

from thread meh: -2

from thread bleh: -1

from thread bleh: 0

from thread bleh: 1

from thread meh: 0

from thread bleh: 1

from thread meh: 0

from thread bleh: 1

from thread meh: 0

from thread meh: -1

from thread bleh: 0

from thread bleh: 1

from thread meh: 0

from thread bleh: 1

from thread bleh: 2

from thread meh: 1

from thread meh: 0

from thread meh: -1

from thread bleh: 0

从线程meh:-1

从线程meh:-2

来自线程 bleh:-1

从线程 bleh: 0

来自线程 bleh:1

从线程meh:0

来自线程 bleh:1

从线程meh:0

来自线程 bleh:1

从线程meh:0

从线程meh:-1

从线程 bleh: 0

来自线程 bleh:1

从线程meh:0

来自线程 bleh:1

来自线程 bleh:2

从线程meh:1

从线程meh:0

从线程meh:-1

从线程 bleh: 0

You block the access to int1, but you can't control one thread to execute two times before the other one is triggered as you can see.

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

This could be useful using another Example, for example with a File, It can't be accesed from two threads at a time or it will give a exception.

使用另一个 Example 可能很有用,例如 File,它不能同时从两个线程访问,否则会产生异常。

Here you have the example:

这里有一个例子:

 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

This example wrote 26814 lineson the path file without any exception in some seconds, so concurrent access to the resource did not happen.

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