C#监视器。如果对象位于另一个对象内,请输入not lock
我认为Monitor.Enter对对象的引用有效,只要对对象或对象本身的引用不变 这是我的简单例子,我有一个名为QueueManager的类,其中有一个队列。我正在使用此对象队列在操作队列之前使用Monitor.lock进行锁定。我尝试了一个调用Monitor.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
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:然后把它作为一个新问题发布。。。国际海事组织回答了这个问题。