如何在没有循环的情况下等待布尔值(使用任何类型的wait / semaphore / event / mutex等)

时间:2012-09-13 18:02:58

标签: c# .net multithreading mutex semaphore

我需要停止一个线程,直到另一个线程设置一个布尔值,我不想在它们之间共享一个事件

我目前所拥有的是使用Sleep的以下代码(这是我想要更改的代码):

while (!_engine.IsReadyToStop())
{
    System.Threading.Thread.Sleep(Properties.Settings.Default.IntervalForCheckingEngine); 
}

有什么想法吗?

编辑澄清事实:

我不拥有一个名为_engine的对象。我无法修改它,这就是为什么我不想在它们之间共享事件。我需要等到该类的方法返回true。

4 个答案:

答案 0 :(得分:24)

SpinWait.SpinUntil是正确的答案,无论您将在何处放置此代码。 SpinUntil提供"a nice mix of spinning, yielding, and sleeping in between invocations"

答案 1 :(得分:12)

如果您使用的是C# 4.0,则可以使用:

Task t = Task.Factory.StartNew (() => SomeCall(..));
t.Wait();

使用Task.Wait方法。

如果您有多个任务一个接一个地运行,您可以使用Task.ContinueWith

 Task t = Task.Factory.StartNew (() =>SomeCall(..)).
                                ContinueWith(ExecuteAfterThisTaskFinishes(...);
 t.Wait();

答案 2 :(得分:4)

声明为

 AutoResetEvent _ReadyToStop = new AutoResetEvent(false);

并用作

 _ReadyToStop.WaitOne();

 _ReadyToStop.Set();

有关详细信息,请参阅Synchronization Primitives in .Net

答案 3 :(得分:0)

条件变量是可用于等待条件的同步原语。

它本身不存在于.NET中。但是,以下link为根据SemaphoreSlim,AutoResetEvent和Monitor类实现的条件变量类提供了100%托管代码。它允许线程在某个条件下等待。并且当条件满足时可以唤醒一个或多个线程。此外,它还支持超时和CancellationTokens。

要等待条件,您可以编写类似于以下内容的代码:

object queueLock = new object();

ConditionVariable notEmptyCondition = new ConditionVariable();

T Take() {

  lock(queueLock) {

    while(queue.Count == 0) {

      // wait for queue to be not empty
      notEmptyCondition.Wait(queueLock);
    }

    T item = queue.Dequeue();

    if(queue.Count < 100) {

      // notify producer queue not full anymore
      notFullCondition.Pulse();
    }

    return item;
  }
}

然后在另一个线程中,您可以唤醒一个或多个等待条件的线程。

lock(queueLock) {

  //..add item here

  notEmptyCondition.Pulse(); // or PulseAll
}