Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Monitor.TryEnter / Monitor.Exit and SynchronizationLockException

Is it possible to detect if the same thread trying to release the lock? We have many places in code that looks like:

try
{
    try
    {
       if(!Monitor.TryEnter(obj, 2000)) 
       { 
            throw new Exception("can not lock"); 
       }
    }
    finally
    {
       Monitor.Exit(obj);
    }
}
catch
{
    //Log
}

The above code very simplified, and actually Enter and Exit statement located in custom object (lock manager).

The problem, that in that structure, we have SynchronizationLockException when trying to "Exit", since it looks like the thread that not succeed to lock, tries to release in finally.

So the question, is how I can know if the thread who making Monitor.Exit is the same thread who did Monitor.Enter?
I thought that I can use CurrentThread.Id to sync enter and exit, but I'm not sure if it "safe" enough.

like image 820
Alex Dn Avatar asked Dec 30 '12 09:12

Alex Dn


1 Answers

So the question, is how I can know if the thread who making Monitor.Exit is the same thread who did Monitor.Enter?

You can't, easily, as far as I'm aware. You can't find out which thread owns a monitor.

However, this is just a coding issue - you should change your code so that it doesn't even attempt to release the monitor when it shouldn't. So your code above could be rewritten as:

if (!Monitor.TryEnter(obj, 2000))
{
    throw new Exception(...);
}
try
{
    // Presumably other code
}
finally
{
     Monitor.Exit(obj);
}

Or even better, if you're using .NET 4, use the overload of TryEnter which accepts an ret parameter:

bool gotMonitor = false;
try
{
    Monitor.TryEnter(obj, ref gotMonitor);
    if (!gotMonitor)
    {
        throw new Exception(...);
    }
    // Presumably other code
}
finally
{
    if (gotMonitor)
    {
        Monitor.Exit(obj);
    }
}
like image 142
Jon Skeet Avatar answered Oct 02 '22 16:10

Jon Skeet