简体   繁体   中英

How to make a method which only runs if the calling thread holds a lock?

In my unsafe class below, what can be done to prevent someone from executing the unsafe method without first obtaining the lock?

class Unsafe
{
    private static readonly object lockObj;

    void MethodA()
    {
        lock (lockObj)
        {
            // do some things
            DoUnsafeThing();
        }
    }

    void MethodB()
    {
        lock (lockObj)
        {
            // do some things
            DoUnsafeThing();
        }
    }

    void DoUnsafeThing()
    {
        if (callerHasLock)
            // Do the unsafe thing
        else
            return; // or throw some exception
    }
}

Obtaining the lock again inside DoUnsafeThing() is an option:

void DoUnsafeThing()
{
    lock (lockObj)
    {
        // Do the unsafe thing
    }
}

But DoUnsafeThing() can now be called by threads that don't already possess the lock.

You should be able to use Monitor.IsEntered() to verify that the thread itself has already obtained the lock:

void DoUnsafeThing()
{
    if (Monitor.IsEntered(lockObj))
        // Do the unsafe thing
    else
        return; // or throw some exception
}

You can use the Monitor class to work with locks. In C#, the lock(...) statement is just syntactic sugar for Monitor.Enter(o); try {...} finally {Monitor.Exit(o);} Monitor.Enter(o); try {...} finally {Monitor.Exit(o);} . There are other options within it for fine-tuning. Remember, multi-threading is Hard. Know your toolset.

EDIT: (in response to framework version question update)

Prior to .NET 4.5, AFAIK the only way to handle this would be to use a thread-static Boolean alongside the synchronization object, set to true just after entering and false just before exiting. That same Boolean--call it callerHasLock , to conform with your code above--can then be tested within the lock context with the same result as Monitor.IsEntered .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM