C#监视器。如果对象位于另一个对象内,请输入not lock

C#监视器。如果对象位于另一个对象内,请输入not lock,c#,object,locking,C#,Object,Locking,我认为Monitor.Enter对对象的引用有效,只要对对象或对象本身的引用不变 这是我的简单例子,我有一个名为QueueManager的类,其中有一个队列。我正在使用此对象队列在操作队列之前使用Monitor.lock进行锁定。我尝试了一个调用Monitor.Lock的简单测试,但失败了。知道为什么吗 public class QueueManager { private List<ConversionJob> _jobQueue = new List<Convers

我认为Monitor.Enter对对象的引用有效,只要对对象或对象本身的引用不变

这是我的简单例子,我有一个名为QueueManager的类,其中有一个队列。我正在使用此对象队列在操作队列之前使用Monitor.lock进行锁定。我尝试了一个调用Monitor.Lock的简单测试,但失败了。知道为什么吗

public class QueueManager
{
    private List<ConversionJob> _jobQueue = new List<ConversionJob>();

    public QueueManager()
    {
    }

    public List<ConversionJob> Queue
    { get { return _jobQueue; } }
}

public class Main
{
    private QueueManager qMgr = new QueueManager();

    public Main()
    {
        try
        {
            Monitor.Enter(qMgr.Queue);
            throw new Exception();
        }
        catch (Exception)
        {
            Monitor.Enter(qMgr.Queue);
        }
    }
}
公共类队列管理器
{
私有列表_jobQueue=新列表();
公共队列管理器()
{
}
公共列表队列
{get{return}jobQueue;}
}
公共班机
{
private QueueManager qMgr=new QueueManager();
公用干管()
{
尝试
{
Monitor.Enter(qMgr.Queue);
抛出新异常();
}
捕获(例外)
{
Monitor.Enter(qMgr.Queue);
}
}
}
这不是死锁!!我不明白为什么它没有死锁。我尝试了这个,因为我怀疑锁被占用了,所以我把这个测试代码放进去,我很惊讶。

监视器是可重入的-一个线程可以多次拥有一个监视器。只有当
Exit
被调用的次数与
Enter
相同时,监视器才会解锁(可供其他线程获取)

从以下文件:

调用线程必须拥有obj参数的锁。如果调用线程拥有指定对象上的锁,并且对该对象进行了相同数量的Exit和Enter调用,则该锁将被释放。如果调用线程调用Exit的次数没有调用Enter那么多,则不会释放锁

这不是死锁


这是因为对
Enter()
的两个调用都来自同一个线程。监视器是递归可重入的。

谢谢,那么假设没有引发异常,而是引发了一个真正的异常,我正在使用以下代码释放锁:
Monitor.TryEnter(_qMgr.Queue,1);//尝试获取锁监视器。退出(_qMgr.Queue);//释放锁
在这种情况下,此操作不起作用。那么,我如何知道锁是否被拿走了?@user2280961:在注释中添加代码很少是个好主意。但基本上,您应该始终使用
lock
语句,而不是手动调用
Enter
Exit
。请注意,
Monitor.TryEnter
返回一个
bool
(或接受一个
out
参数)以指示成功或失败。是,但TryEnter将始终获取锁,因为它是递归重入的。所以这对我的情况没有帮助,对吗?@user2280961:如果你告诉我们你想要完成什么,也许会有帮助。@rboy:然后把它作为一个新问题发布。。。国际海事组织回答了这个问题。