是否可以检测同一线程是否试图释放锁?
我们在代码中有很多地方,例如:

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

上面的代码非常简化,实际上Enter和Exit语句位于自定义对象(锁管理器)中。

问题在于,在该结构中,尝试“退出”时会出现SynchronizationLockException,因为它看起来好像未成功锁定的线程最终试图释放。

因此,问题是,如何确定Monitor.Exit的线程与Monitor.Enter的线程是否相同?
我以为可以使用CurrentThread.Id同步进入和退出,但是我不确定它是否“足够安全”。

最佳答案

正如您认为在try-catch中调用Monitor.Exit的调用是“脏”(脏吗?)一样,这是一个非常简单的想法,试图“消除脏污”。对于同一线程,锁是可重入的,并且如果一个线程成功释放,则在释放之前,从另一个线程进行的尝试将失败。这样您就可以考虑以下内容:

public void Exit(object key) {
    if(!IsActive) {
        return;
    }

    if(LockDictionary.ContainsKey(key)) {
        var syncObject=LockDictionary[key];

        if(Monitor.TryEnter(syncObject.SyncObject, 0)) {
            SetLockExit(syncObject);
            Monitor.Exit(syncObject.SyncObject);
            Monitor.Exit(syncObject.SyncObject);
        }
    }
}

我们将Monitor.Exit调用两次是因为我们将其锁定了两次,一次在代码外部,一次在这里。

关于c# - Monitor.TryEnter/Monitor.Exit和SynchronizationLockException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14089640/

10-12 18:39