This is going to be a bit complicated, and I strongly recommend you find a book and read up on multithreading, because it is quite important that you understand what (and why) it happens. The lock keyword requires you to specify a token (an object reference) that must be acquired by a thread to enter within the lock scope. When you are attempting to lock down a private instance-level method, you can simply pass in a reference to the current type:
private void SomePrivateMethod()
{
// Use the current object as the thread token.
lock(this)
{
// All code within this scope is thread-safe.
}
}
However, if you are locking down a region of code within a public member, it is safer (and better practice) to declare a private object member variable to serve as the lock token:
public class MyClass
{
// Lock token.
private object threadLock = new object();
public void MyMethod()
{
// Use the lock token.
lock (threadLock)
{
...
}
}
}
Why does it have to be an object? Why can't it be an integer? Or a bool? This is more complex, and it goes back to the beginnings of what you probably learnt when you were starting. Do you remember all that suff about Value types and Reference types? Well, the lock token must be a reference type, because otherwise when you pass it to the lock block, it would get re-packaged into a reference type container, which would then be locked. If a second thread came along and passed it to a lock block again, it gets re-packaged again, and a different reference type container gets locked. Remember that (like so many things in C#) "lock(token)" is a "short cut" for a method call - in this case Monitor.Enter and Monitor.Exit - so you are actually passing the token to a method. The parameter works teh same as it would for any other method, packaging and all. Does this make sense? It is a bit complicated!
No trees were harmed in the sending of this message; however, a significant number of electrons were slightly inconvenienced. This message is made of fully recyclable Zeros and Ones