21

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

我目前拥有的是使用睡眠的以下代码(这就是我要更改的代码):

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

有任何想法吗?

编辑以澄清事情:

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

4

4 回答 4

33

SpinWait.SpinUntil是正确的答案,无论您将此代码放在哪里。SpinUntil 提供了“在调用之间的旋转、屈服和休眠的完美组合”

于 2015-12-11T23:08:27.763 回答
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();
于 2012-09-13T18:05:52.720 回答
4

声明为

 AutoResetEvent _ReadyToStop = new AutoResetEvent(false);

并用作

 _ReadyToStop.WaitOne();

 _ReadyToStop.Set();

有关更多信息,请参阅.Net 中的同步原语

于 2012-09-13T18:04:56.990 回答
0

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

它本身并不存在于 .NET 中。但以下链接为根据 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
}
于 2018-03-01T13:01:07.023 回答