Checking whether the current thread owns a lock

Locking or re-locking are effectively free. The downside of this low cost is that you don't have as many features as the other synchronisation mechanisms. I would simply lock whenever a lock is vital, as you have above.

If you desparately want to omit 'unnecessary' locks without the risk involved with potential refactoring, add comments. If someone changes your code and it breaks, there is a comment there that explains why. If they still can't figure it out, that's their problem, not yours. A further alternative is to create a class for use as a locking object that contains a boolean you can flick on and off. However, the overheads introduced by doing this (including try/finally blocks, which are not free), are probably not worth it.


But there does not appear to be such a method. Monitor.TryEnter does not help because locks are re-entrant. Therefore, if the current thread already owns the lock, TryEnter will still succeed and return true. The only time it will fail is if another thread owns the lock and the call times out.

I found a workaround that works similar to Monitor.TryEnter() and yet doesn't have the re-entrant issues. Basically instead of using Monitor.TryEnter(), you can use Monitor.Pulse(). This function throws a SynchronizationLockException exception if the current thread doesn't hold the lock.

example:

try
{
    System.Threading.Monitor.Pulse(lockObj);
}
catch (System.Threading.SynchronizationLockException /*ex*/)
{
    // This lock is unlocked! run and hide ;)
}

Docs: http://msdn.microsoft.com/en-us/library/system.threading.monitor.pulse.aspx


This is supported in .NET 4.5 using Monitor.IsEntered(object).


There's a fundamental problem with your request. Suppose there were a IsLockHeld() method and you'd use it like this:

if (not IsLockHeld(someLockObj)) then DoSomething()

This cannot work by design. Your thread could be pre-empted between the if() statement and the method call. Allowing another thread to run and lock the object. Now DoSomething() will run, even though the lock is held.

The only way to avoid this is to try to take the lock and see if it worked. Monitor.TryEnter().

You see the exact same pattern at work in Windows. There is no way to check if a file is locked by another process, other than trying to open the file. For the exact same reason.