A follow-up to this post. My goal is to have only one Calculate
at a time, so I have added a 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
Note the isBack
. If this is false the code should just run in main. This is commonly used when recalculating a single Line
. So my question is about the safety of these two lines:
SyncLock Lock
Threading.Thread.MemoryBarrier()
It is not clear to me in the documentation what happens if I call these in code running in main. I have added the code, and it seems to run OK, but I want to make sure I'm not opening myself to another gotcha, like Abort. Are these OK for both threaded and non-threaded uses?
Yes it's safe to use them in single threaded code.
There are issues however with your InternalCalculate
which will allow it to execute code concurrently. Every call to InternalCalculate
creates a new Lock
object. Synclock
will only block threads if these use the same object so make Lock
a readonly member variable.
If you then execute multiple threads then the second, third, fourth etc will wait until the first one to obtain the lock exits the sync lock block. Then the others will go. So if this is code that should only be executed once you should check out the double check lock pattern.
Instead of adding MemoryBarriers
for the reading / writing of volatile data, I'd suggest you use System.Threading.Thread.VolatileRead
and System.Threading.Thread.VolatileWrite
. Then you don't need to remember which order to do your reads / writes in.