views:

111

answers:

3

I have objects, they get locks. I want to test if they are locked without acquiring a lock. The idea is if I TryEnter() they i have to Exit() if true to only check the lock correctly.

Seems like a really basic question, how is it done?

+11  A: 

What possible information can you get from knowing the lock was unlocked back when you looked at it? By the time you make a decision based on that information, the lock may be already taken.

Remus Rusanu
+1, exactly. Answering this question about the past state of the lock can only lead you to making incorrect decisions.
JaredPar
I lock things so that i can see if they are being used. e.g. So two threads don't smash the same shared resources. I want to see if that work is being done. I could do the same thing with a IsBeingUsed value but the object for the lock already exists and the locks act the same way, with the exception of being able to check if they are locked with out setting the value to locked.
JustSmith
When you examine IsBeingUsed, the thread may already have stopped useful work but a context switch may have happened before IsBeingUsed was updated.
Eric J.
@Eric: or worse: IsBeingUsed is 0 and you go ahead and do changes, oblivious to the fact that in the meantime someone did change it to 1.
Remus Rusanu
I can see a use for this kind of behaviour. Imagine a situation wherein a lock is acquired for a long period of time, and two threads need to do different things to the same set of objects. If the two collection operations are not order-dependent, then it could be useful to peek at an object first, and skip it to be processed in a later pass if it is in use.
Tullo
@Tullo: But that can be solved better with an zero wait acquire like Monitor.TryEnter. Zero wait aquire means you are willing to grab the lock if is free, but not willing to wait. The OP asked for different semantics, ie. *peek* without acquire. I really can't see any real use for such semantics.
Remus Rusanu
A: 

Because the lock statement is equivalent to:

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

Can you just do this?

bool ObjectWasUnlocked(object x)
{
   if(System.Threading.Monitor.TryEnter(x))
   {
       System.Threading.Monitor.Exit(x);
       return true;
   }
   else
   {
       return false;
   }
}

Note that I'm naming this function "ObjectWasUnlocked" as opposed to "ObjectIsUnlocked". There is no guarantee that it will still be unlocked when the function has returned.

Andrew Shepherd
In this solution though you acquire the lock which is something the OP did not want to do.
JaredPar
@JaredPar: Yep, good point.
Andrew Shepherd
A: 

Here is a related question

http://stackoverflow.com/questions/496388/checking-whether-the-current-thread-owns-a-lock

The conclusion there was 'you can't'

Phil