代码之家  ›  专栏  ›  技术社区  ›  Doug Ferguson

监视器会发生什么情况。在没有匹配监视器的情况下进入。退出?

  •  7
  • Doug Ferguson  · 技术社区  · 14 年前

    如果您有一些代码块希望在退出和清除对象时阻止执行,可以使用锁来阻止执行吗?

    Monitor.TryEnter(cleanupLock, ref acquiredLock);
    

    TryEnter可用于确保代码未被执行,并且由于它不等待锁,因此不会出现死锁。

    另一个线程在确定该关闭时会获取锁。

    Monitor.Enter(cleanupLock);
    

    如果清除线程从不调用

    Monitor.Exit(cleanupLock);
    

    这会引起问题吗?

    4 回复  |  直到 14 年前
        1
  •  8
  •   JaredPar    14 年前

    是的,不打电话 Monitor.Exit 为了成功 Monitor.TryEnter Monitor.Enter 是应用程序中死锁的快速通道。你可以让它在 非常 有限的场景,但最终代码或场景会改变,这 回来咬你。别这么做。

        2
  •  6
  •   Reed Copsey    14 年前

    唯一的“问题”是,没有其他代码能够获取cleanuplock变量的锁。

    这可能是一个问题,也可能不是问题——但是,这有点像滥用监视器,所以我会避免这样做。在我看来,以一种更普遍的方式处理这种情况会更好。

        3
  •  1
  •   Remus Rusanu    14 年前

    如果这是一个清理关闭序列,那么它或多或少是正常的。你会冒着有人在某个地方登记的风险,因为你错了,你会等待获得cleanuplock。它可以在不被注意的情况下滑入代码,并在最混乱的时刻出现。结果将是一个拒绝关闭的线程,可能会使进程处于活动状态并令人恶心。但是,在一天结束时,使用任何其他方法(例如全局关闭标志)都会产生相同的风险。

        4
  •  0
  •   Randolpho    14 年前

    这会引起问题吗?

    对。锁永远不会被释放。

    Source :

    调用线程必须拥有obj参数的锁。如果调用线程拥有指定对象上的锁,并且对该对象进行了等量的退出和输入调用,则释放该锁。如果调用线程没有像enter那样多次调用exit,则不会释放锁。