I was trying to lock
a Boolean
variable when I encountered the following error :
\'bool\' is not a reference type as require
Just a wild guess here...
but if the compiler let you lock on a value type, you would end up locking nothing at all... because each time you passed the value type to the lock
, you would be passing a boxed copy of it; a different boxed copy. So the locks would be as if they were entirely different objects. (since, they actually are)
Remember that when you pass a value type for a parameter of type object
, it gets boxed (wrapped) into a reference type. This makes it a brand-new object each time this happens.
I was wondering why the .Net team decided to limit developers and allow Monitor operate on references only. First, you think it would be good to lock against a System.Int32
instead of defining a dedicated object variable just for locking purpose, these lockers don't do anything else usually.
But then it appears that any feature provided by the language must have strong semantics not just be useful for developers. So semantics with value-types is that whenever a value-type appears in code its expression is evaluated to a value. So, from semantic point of view, if we write `lock (x)' and x is a primitive value type then it's the same as we would say "lock a block of critical code agaist the value of the variable x" which sounds more than strange, for sure :). Meanwhile, when we meet ref variables in code we are used to think "Oh, it's a reference to an object" and imply that the reference can be shared between code blocks, methods, classes and even threads and processes and thus can serve as a guard.
In two words, value type variables appear in code only to be evaluated to their actual value in each and every expression - nothing more.
I guess that's one of the main points.
According to this MSDN Thread, the changes to a reference variable may not be visible to all the threads and they might end up using stale values, and AFAIK I think value types do make a copy when they are passed between threads.
To quote exactly from MSDN
It's also important to clarify that the fact the assignment is atomic does not imply that the write is immediately observed by other threads. If the reference is not volatile, then it's possible for another thread to read a stale value from the reference some time after your thread has updated it. However, the update itself is guaranteed to be atomic (you won't see a part of the underlying pointer getting updated).