views:

86

answers:

3

Hello,

I have this code in a class:

private static MyObject _locker = new MyObject();

...

lock (_locker)
{
     ...
     _locker = new MyObject();
     ...
}

Will it keep the lock on _locker ?

+6  A: 

No, it will not. From the C# specification (emphasis is mine):

A lock statement of the form lock (x) ... where x is an expression of a reference-type, is precisely equivalent to

System.Threading.Monitor.Enter(x);
try {
  ...
}
finally {
  System.Threading.Monitor.Exit(x);
}

except that x is only evaluated once.

Since x is not reevaluated the lock will be released.

João Angelo
lock keyword is syntactical sugar. If you were coding in managed c++ with .net framework 1.1, you would have had to lock the way João has specified.
Sudesh Sawant
Right on the spot Joao. Thank you.
Theo Zographos
+2  A: 

Don't do this. Consider using a separate object entirely to hold the state of the lock, not necessarily the object you want to protect in the lock statement. I often write code (ok, not often) like this:

private static readonly object _locker = new object();
private static MyObject _object;
...

lock (_locker)
{
     ...
     _object = new MyObject();
     ...
}

It involves a completely different sort of program flow than what you're looking at. lock() defines a critical section in the code -- you don't use it as an all-purpose thread safety mechanism for any type of object (which is what I think your intent is in your code?)

Dave Markle
And declare `_locker` as `readonly` so that it can't be accidentally re-assigned.
LukeH
Great idea. Edited accordingly.
Dave Markle
I wish I could create a state object without complicating things.
Theo Zographos
+2  A: 

I assume it will keep the lock on the MyObject instance that was set to _locker when lock has been called, i.e. it will keep the lock on the original instance of _locker, not on the newly created MyObject instance. In the following code, the lock will be kept on MyObject("OriginalInstance") when the lock is called for the first time. When it is called the second time, it will lock on MyObject("NewInstance").

private static MyObject _locker = new MyObject("OriginalInstance");

...

lock (_locker)
{
    ...
    _locker = new MyObject("NewInstance");
    ...
}

Therefore, the next thread may enter the critical section without problems because the new instance is not locked.

Anyway, doing stuff like this is generally considered bad practice. See MSDN for some advices on how to use lock.

gehho
Well.. it is a bad practice indeed. I need to find ways to prevent the reinstanciation from happening.
Theo Zographos
Declare the variable as `readonly`, as already stated by others here.
gehho