Monitor.TryEnter / Monitor.Exit和SynchronizationLockException [英] Monitor.TryEnter / Monitor.Exit and SynchronizationLockException

查看:205
本文介绍了Monitor.TryEnter / Monitor.Exit和SynchronizationLockException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以检测,如果同一个线程试图释放锁? 我们有很多地方在code,它是这样的:

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
}

以上code非常简单,实际上进入和退出声明中位于自定义对象(锁管理器)。

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

的问题,即在该结构中,我们有 SynchronizationLockException 想退出的时候,因为它看起来像没有成功锁的线程,试图释放最后。

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.

所以,问题是我如何知道谁做Monitor.Exit线程是谁做Monitor.Enter同一个线程?
我以为我可以使用CurrentThread.Id同步进入和退出,但我不知道这是否安全够了。

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.

推荐答案

当你认为把Monitor.Exit的通话中的try-catch是的Durty(脏),这里是一个非常简单的想法努力采取的Durty走。锁是可重入的同一个线程,如果一个线程成功收购,它释放之前,尝试从另一个线程将失败。所以,你可以考虑这样的:

As you think that to put the calling of Monitor.Exit in try-catch was 'durty'(dirty?), here's a very simple idea trying to 'take the durty away'. Lock is reentrant for the same thread and if one thread acquired successfully, before it releases, attempt from another thread will fail. So that you can consider something like:

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两次,因为我们锁定了两次,一次在code外,还有一个就在这里。

We call Monitor.Exit twice because we lock it twice, one in the code outer, and one just here.

这篇关于Monitor.TryEnter / Monitor.Exit和SynchronizationLockException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆