.NET Thread.Sleep () ist zufällig ungenau

In meiner .NET-Anwendung muss ich eine Reihe von Sensorereignissen wiedergeben. Also habe ich einen Thread erstellt, der diese Ereignisse auslöst (normalerweise alle 1 - 4 Millisekunden). Ich habe eine Schleife in diesen Thread implementiert und verwendetThread.Sleep(...) den Faden zwischen den Ereignissen schlafen zu legen.

Grundsätzlich sieht es so aus:

void RunThread() {
  var iter = GetAllEvents().GetEnumerator();
  if (!iter.MoveNext()) {
    return;
  }

  DateTime lastEventTime = iter.Current.Timestamp;
  FireEvent(iter.Current);

  while (iter.MoveNext()) {
    MyEvent nextEvent = iter.Current;

    int timeout = (int)(nextEvent.Timestamp - lastEventTime).TotalMilliseconds; 
    Thread.Sleep(timeout);

    FireEvent(nextEvent);
    lastEventTime = nextEvent.Timestamp;
  }
}

Nun, mein Problem ist dasThread.Sleep() Manchmal wird das angegebene Zeitlimit eingehalten, manchmal nicht.

Ich habe einen Scheck hinzugefügt (mitStopWatch, im obigen Code nicht sichtbar), wie lange der Schlaf tatsächlich gedauert hat. Hier sind einige Ergebnisse:

Expected timeout of 1 ms but got 15 ms.
Expected timeout of 2 ms but got 13 ms.
Expected timeout of 3 ms but got 15 ms.
Expected timeout of 2 ms but got 13 ms.
Expected timeout of 1 ms but got 13 ms.
Expected timeout of 1 ms but got 15 ms.
Expected timeout of 2 ms but got 13 ms.
Expected timeout of 2 ms but got 40 ms.

Warum tutThread.Sleep() benimmst du dich das "zufällig"?

Anmerkungen:

Der Windows-Task-Manager zeigt keine CPU-Auslastung an, während dieser Thread ausgeführt wird.Das Verhalten ändert sich zufällig, bleibt jedoch mindestens einige Sekunden lang bestehen. Wenn ich zum Beispiel den Thread einmal starte, läuft er einwandfrei. Das nächste Mal läuft es die ganze Zeit langsam. Beim nächsten Mal läuft es ein paar Sekunden schnell, dann wird es langsamer oder umgekehrt.

Aktualisieren: Hier ist ein Pseudocode, der zeigt, wieSleep verhält:

bool ChooseRespectTimeout() {
  if (this.notYetChosen) {
    this.respectTimeout = ChooseRandomly()
    this.notYetChosen = false
    reset this.notYetChosen after random time period
  }
  return this.respectTimeout
}

void Sleep(int timeout) {
  if (ChooseRespectTimeout())
    Thread.Sleep(timeout)
  else
    Thread.Sleep(timeout * 10)
}

Antworten auf die Frage(7)

Ihre Antwort auf die Frage