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

问题描述 投票:16回答:4

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

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

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

有任何想法吗?

编辑澄清事:

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

c# .net multithreading mutex semaphore
4个回答
24
投票

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


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();

4
投票

声明为

 AutoResetEvent _ReadyToStop = new AutoResetEvent(false);

并用作

 _ReadyToStop.WaitOne();

 _ReadyToStop.Set();

有关更多信息,请参阅Synchronization Primitives in .Net


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
}
© www.soinside.com 2019 - 2024. All rights reserved.