Hrm... I'm using VB.NET Express 2010, and haven't actually been able to find any problems with the SyncLocking, no matter how I declared the lock object. I created a very simple demo to test it, and whether the lock object was declared like:
Dim objLock As New Object
Dim objLock As Object = New Object
Dim objLock As Object
objLock = New Object
Any of the three, the SyncLock continued to work. It's possible that it was fixed in 2010, but I suspect not, as I haven't seen anything mentioning it in the release notes. Maybe there's an issue with how you're scoping your lock object?
Here's how I did it. First, I create an object to pass parameters to my thread, since I can only pass one object as a parameter (this has changed with 2K8, but then it only worked with functions, and with 2010 you could pass multiple parameters to subs, but with both Microsoft's "solution" is sloppy and convoluted, so I stick with passing all of my parameters as a single thread parameter object.)
Private Class ThreadParams
Public FileName As String
Public objLock As Object
Public Value As String
End Class
I will be passing a filename, a value for the line to put in the file, and notice that the objLock is explicitly NOT declared as "New" here. The reason will become more obvious later.
Now I declare all of my objects in the main thread, and fire off both threads simultaneously:
Public Sub Main()
Dim t1 As Thread, t2 As Thread, thrParam1 As ThreadParams, thrParam2 As ThreadParams
thrParam1 = New ThreadParams
thrParam2 = New ThreadParams
t1 = New Thread(AddressOf WriteText)
t2 = New Thread(AddressOf WriteText)
thrParam1.objLock = New Object
thrParam2.objLock = thrParam1.objLock
thrParam1.FileName = Application.StartupPath & "\Test.txt"
thrParam2.FileName = Application.StartupPath & "\Test.txt"
thrParam1.Value = "This is the FIRST thread running."
thrParam2.Value = "This is the SECOND thread running."
t1.Start(thrParam1)
t2.Start(thrParam2)
End Sub
Very important point here: The lock object for the first, and only the first parameter object is created as "new." Any subsequent threads need to use that SAME lock object, so the second parameter's lock object gets set equal to the first lock object. Then I set the other values, and fire up the threads. The threads just look like this:
Private Sub WriteText(ByVal thrParam As ThreadParams)
Dim sw As StreamWriter, strLine As String, intTick As Integer
SyncLock thrParam.objLock
sw = New StreamWriter(thrParam.FileName, True)
intTick = System.Environment.TickCount + 1000
Do While intTick > System.Environment.TickCount
strLine = CStr(System.Environment.TickCount) & " - " & thrParam.Value
sw.WriteLine(strLine)
Loop
sw.Close()
End SyncLock
End Sub
The threads can receive a single object as their parameter, so I pass the ThreadParams object. Just before opening the file (starting the writing stream) I lock the objLock to make sure that I'm the only one trying to muck with the file. I then release the object when I'm done. When you look at the output file, you'll see that even though these threads were started simultaneously, the first thread will write to it for a full 1 second while the second thread waits patiently for its turn. Once the object is "unlocked" the second thread then writes to the file for a full second.
You can also use multiple lock objects within a single thread. Suppose you have multiple files that you will need to write to in the same thread. You can have a separate objLock for each. You do have to be cautious about thread deadlocks though, but this can be easily avoided if you make sure that a single thread only locks a single object at any one time.