【问题标题】:Monitor.Wait Initially Locked?Monitor.Wait 最初被锁定?
【发布时间】:2016-08-07 11:49:45
【问题描述】:

背景

我正在尝试编写执行以下操作的应用程序:

  1. 我对@9​​87654323@进行了方法调用。
  2. 此方法调用块,直到我从另一个线程调用 SomeUnblockingMethod
  3. 当调用SomeUnblockingMethod 时,SomeBlockingMethod 内部的例程将继续。

注意,我首先会拨打SomeBlockingMethod,然后我会拨打SomeUnblockingMethod。我正在考虑使用Monitor.Wait/Monitor.Pulse 机制来实现这一点。唯一的事情是,当有人调用Monitor.Wait 时,你不能一开始就阻止,除非所涉及的object 已经被其他东西锁定(或者至少我不知道)......但是,我想要 阻止 成为我做的第一件事...所以这引出了我的问题...

问题

有没有什么方法可以实现Monitor.Wait 以最初阻止直到调用Monitor.Pulse

【问题讨论】:

  • @Sinatr 也许我很困惑输入...让我试一试。会尽快回复您。
  • 您想使用Monitor.Wait()的重载,您可以在其中指定超时时间(例如Infinity)。
  • @Sinatr 是的,你是对的......因为我最初阻止了,这是个好主意。
  • A AutoResetEvent 仍然会阻塞调用线程,直到您发出信号。我建议可能存在根本不需要的解决方案。
  • 好吧,难怪你不知道如何编写正确的代码。

标签: c# .net multithreading locking thread-synchronization


【解决方案1】:

您可以改用AutoResetEvent

AutoResetEvent ar = new AutoResetEvent(false); // false set initial state as not signaled

然后你可以使用ar.WaitOne() 来等待,ar.Set() 来表示等待进程。

当您想要保护资源或拥有critical section 时,您应该使用 Monitor。如果你想要一个信号机制,那么AutoResetEventManualResetEvent 听起来是一个更好的选择。

【讨论】:

  • 所以您根本不建议为此使用监视器?为什么?
  • @StevieV,这只是另一种可能的解决方案。不需要从lightweight Monitor切换到AutoResetEvent,除非你想synchronize different processes
  • 我说你不​​能你必须。 @StevieV
【解决方案2】:

我不知道是什么问题,但你想要的已经是它的工作原理了:

object _lock = new object();

void SomeBlockingMethod()
{
    lock(_lock)
        Monitor.Wait(_lock);
    ... // here only after pulse
}

void SomeUnblockingMethod()
{
    lock(_lock)
        Monitor.Pulse(_lock);
}

也许你从多个地方调用SomeBlockingMethod,然后你想使用PulseAll。或者SomeUnblockingMethod 被称为之前 SomeBlockingMethod

【讨论】:

  • 如果阻塞方法已经进入lock区域,那么解锁方法是否可以进入lock区域?我想解除阻塞方法需要进入该区域才能脉冲阻塞方法。对吗?
  • 调用Monitor.Wait()时释放锁,以便其他方法获取锁和脉冲。 Read more.
猜你喜欢
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多