web-dev-qa-db-de.com

Wie man auf einen Boolean ohne Schleife wartet (mit einer beliebigen Art von wait/semaphore/event/mutex usw.)

Ich muss einen Thread anhalten, bis ein anderer Thread einen booleschen Wert setzt und ich möchte kein Ereignis zwischen ihnen teilen.

Was ich derzeit habe, ist der folgende Code mit einem Sleep (und das ist der Code, den ich ändern möchte):

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

Irgendwelche Ideen?

BEARBEITEN, UM DIE DINGE ZU VERGESSEN:

Es gibt ein Objekt namens _engine einer Klasse, das ich nicht besitze. Ich kann es nicht ändern, deshalb möchte ich kein Ereignis zwischen ihnen teilen. Ich muss warten, bis eine Methode dieser Klasse true zurückgibt.

16

SpinWait.SpinUntil ist die richtige Antwort, unabhängig davon, wo Sie diesen Code eingeben. SpinUntil bietet "eine schöne Mischung aus Spinnen, Nachgeben und schlafen zwischen Aufrufen" .

24
MoonStom

Wenn Sie C# 4.0 verwenden, können Sie Folgendes verwenden:

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

Durch Verwendung von Task.Wait Methode.

Wenn Sie mehrere Aufgaben nacheinander ausführen, können Sie Task.ContinueWith verwenden:

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

erklären als

 AutoResetEvent _ReadyToStop = new AutoResetEvent(false);

und verwenden als

 _ReadyToStop.WaitOne();

und 

 _ReadyToStop.Set();

Weitere Informationen finden Sie in den Synchronisationsprimitiven in .Net

4
L.B

Eine Bedingungsvariable ist das Synchronisationsprimitiv, mit dem Sie auf eine Bedingung warten können. 

Es existiert nicht nativ in .NET. Der folgende link stellt jedoch 100% verwalteten Code für eine Bedingungsvariablenklasse bereit, die in Form von SemaphoreSlim-, AutoResetEvent- und Monitor-Klassen implementiert ist. Dadurch kann der Thread auf eine Bedingung warten. Und kann einen oder mehrere Threads aufwecken, wenn die Bedingung erfüllt ist. Darüber hinaus werden Timeouts und Annullierungstoken unterstützt.

Um auf eine Bedingung zu warten, schreiben Sie Code, der dem folgenden ähnelt:

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;
  }
}

Dann können Sie in einem anderen Thread einen oder mehrere Threads aufwecken, die auf Bedingung warten.

lock(queueLock) {

  //..add item here

  notEmptyCondition.Pulse(); // or PulseAll
}
0
gm127