即使您不在单独的线程中,调用 SyncLock 和 MemoryBarrier 是否安全?
Is it safe to call SyncLock and MemoryBarrier even if you're not in a separate thread?
的后续行动。我的目标是一次只有一个Calculate
,所以我添加了一个SyncLock:
Public Sub Calculate(Optional inBack As Boolean = True)
If Not inBack Then
InternalCalculate(-1, False)
Else
If CalcThread IsNot Nothing Then
CalcThread.Abort() ' yes, I will replace this
CalcThread = Nothing ' XXX
End If
If CalcThread Is Nothing Then
CalcThread = New Threading.Thread(AddressOf InternalCalculate)
CalcThread.IsBackground = True
End If
CalcThread.Start()
End If
End Sub
Private Sub InternalCalculate(Optional Line As Integer = -1, Optional isBack As Boolean = True)
Dim Lock As New Object
SyncLock Lock
Threading.Thread.MemoryBarrier() ' do this BEFORE a write, right?
isRunning = true
'do the expensive stuff
End SyncLock
End Sub
注意 isBack
。如果这是错误的,代码应该只是 运行 in main.这通常在重新计算单个 Line
时使用。所以我的问题是关于这两条线的安全性:
SyncLock Lock
Threading.Thread.MemoryBarrier()
我不清楚 the documentation 如果我在主代码 运行ning 中调用它们会发生什么。我已经添加了代码,它似乎 运行 OK,但我想确保我不会让自己陷入另一个陷阱,比如 Abort。这些是否适用于线程和非线程用途?
是的,在单线程代码中使用它们是安全的。
但是您的 InternalCalculate
存在问题,这将允许它并发执行代码。每次调用 InternalCalculate
都会创建一个新的 Lock
对象。 Synclock
只会阻塞线程,如果它们使用相同的对象,所以使 Lock
成为只读成员变量。
如果你随后执行多个线程,那么第二个、第三个、第四个等等将等待,直到第一个获得锁的线程退出同步锁块。然后其他人会去。因此,如果这是只应执行一次的代码,您应该检查双重检查锁定模式。
我建议您使用 System.Threading.Thread.VolatileRead
和 System.Threading.Thread.VolatileWrite
,而不是为读取/写入易失性数据添加 MemoryBarriers
。这样你就不需要记住读/写的顺序了。
Calculate
,所以我添加了一个SyncLock:
Public Sub Calculate(Optional inBack As Boolean = True)
If Not inBack Then
InternalCalculate(-1, False)
Else
If CalcThread IsNot Nothing Then
CalcThread.Abort() ' yes, I will replace this
CalcThread = Nothing ' XXX
End If
If CalcThread Is Nothing Then
CalcThread = New Threading.Thread(AddressOf InternalCalculate)
CalcThread.IsBackground = True
End If
CalcThread.Start()
End If
End Sub
Private Sub InternalCalculate(Optional Line As Integer = -1, Optional isBack As Boolean = True)
Dim Lock As New Object
SyncLock Lock
Threading.Thread.MemoryBarrier() ' do this BEFORE a write, right?
isRunning = true
'do the expensive stuff
End SyncLock
End Sub
注意 isBack
。如果这是错误的,代码应该只是 运行 in main.这通常在重新计算单个 Line
时使用。所以我的问题是关于这两条线的安全性:
SyncLock Lock
Threading.Thread.MemoryBarrier()
我不清楚 the documentation 如果我在主代码 运行ning 中调用它们会发生什么。我已经添加了代码,它似乎 运行 OK,但我想确保我不会让自己陷入另一个陷阱,比如 Abort。这些是否适用于线程和非线程用途?
是的,在单线程代码中使用它们是安全的。
但是您的 InternalCalculate
存在问题,这将允许它并发执行代码。每次调用 InternalCalculate
都会创建一个新的 Lock
对象。 Synclock
只会阻塞线程,如果它们使用相同的对象,所以使 Lock
成为只读成员变量。
如果你随后执行多个线程,那么第二个、第三个、第四个等等将等待,直到第一个获得锁的线程退出同步锁块。然后其他人会去。因此,如果这是只应执行一次的代码,您应该检查双重检查锁定模式。
我建议您使用 System.Threading.Thread.VolatileRead
和 System.Threading.Thread.VolatileWrite
,而不是为读取/写入易失性数据添加 MemoryBarriers
。这样你就不需要记住读/写的顺序了。