2011-01-08 5 views
2

Ich mache einfache Stroboskop am Computer angeschlossen. Ich habe Schleife wie folgt aus:C# Stroboskop, Thread.Sleep

double SleepTime = 1000/Hz; 

while() 
{ 
    BlinkAll(); 
    Thread.Sleep((int)SleepTime); 
} 

Aber das ist sehr ungenau. Wenn Hz = 666 als Sleeptime = 1,5 und (int) Sleeptime = 1

bedeutet dies, dass bei der Ausgabe erhalte ich 1000Hz nicht 666Hz Dieser große diffrence ist.

Wie behebt man das?

P.S.

Dieses Beispiel ist immer noch nicht zu genau. Es ist besser, aber nicht gut in irgendeiner Weise:

double SleepTime = 1000/Hz; 
Thread.Sleep((int)SleepTime + 0.5) 
+5

'Threading.Sleep' ungenau bis zu 15 ms ist, soweit ich weiß, und sie erinnern. Es ist nicht für eine solche Aufgabe verwendbar, nicht einmal genau. – Bobby

+3

Eigentlich ist die Präzision noch nicht einmal annähernd. Obwohl Sie eine Granularität von Millisekunden angeben können, hat der Interrupt, der verwandt wird, eine niedrigere Häufigkeit normalerweise um ungefähr 10 Millisekunden (die sich zwischen verschiedenen Betriebssystemversionen unterscheiden). Das bedeutet, dass Sie tatsächlich etwas wie 100 Hz anstatt 1000 Hz bekommen. – Guffa

+1

Vielleicht möchten Sie sich diese Frage ansehen: [Wie genau ist Thread.Sleep()] (http://stackoverflow.com/questions/1303667/how-accurate-is-thread-sleeptimespan) – Bobby

Antwort

2

bei NtDelayExecution (ntdll.dll) Werfen Sie einen Blick ... scheint es besser Granularität zu haben (Einheiten von 100 ns eher als 1 ms), obwohl ich bin mir nicht sicher, wie viel das wird helfen, weil ich denke, dass Threads unter Windows jeweils ein paar Millisekunden Zeitscheibe benötigen.

+2

Ja, Sie werden diese Granularität oder Konsistenz auf einem Nicht-RTOS einfach nicht erreichen. –

0

haben Sie versucht mit System.Timers.Timer? Ich glaube, es ist sehr viel genauer und Millisekunden akzeptieren, so dass Sie ganz

+3

Sie schlagen immer noch eine Wand bei etwa 15 ms. –

0

Wie wäre es so etwas wie genau sein können:

using System; 
using System.Threading; 
using System.Diagnostics; 

static class Program 
{ 
    static void Main() 
    { 
     const int Hz = 666; 
     var t0 = DateTime.Now; 
     int nCycles = 0; 
     var sw = Stopwatch.StartNew(); 
     while (sw.ElapsedMilliseconds < 10000) 
     { 
      ++nCycles; 
      var time = t0 + TimeSpan.FromMilliseconds(nCycles * 1000/Hz); 
      var ttw = (int)((time - DateTime.Now).TotalMilliseconds); 
      if (ttw >= 1) 
       Thread.Sleep(ttw); 
     } 
     Console.WriteLine(nCycles); 
    } 
} 
+3

Ich sage es noch einmal, 'Thread.Sleep()' [hat nicht die Genauigkeit] (http://stackoverflow.com/questions/1303667/how-accurate-is-thread-sleeptimespan) für 666Hz. Wenn Sie diese Funktion verwenden, erhalten Sie höchstwahrscheinlich etwas zwischen 10ms und 25ms. – Bobby