Frage

Ich lief in etwas unerwartetes Verhalten mit DateTime.UtcNow während einigen Unit-Tests zu tun. Es scheint, dass, wenn Sie DateTime.Now/UtcNow in schnellen Folge nennen, es zu geben scheint, dass Sie den gleichen Wert für ein Rück länger als erwartetes Zeitintervall, anstatt präzise Millisekunden-Schritte zu erfassen.

Ich weiß, dass es eine Stoppuhr-Klasse, die besser dafür präzise Zeitmessungen geeignet wäre, aber ich war neugierig, wenn jemand dieses Verhalten in Datetime erklären könnte? Gibt es eine offizielle Präzision für DateTime.Now dokumentiert (zum Beispiel, und zwar innerhalb von 50 ms?)? Warum soll DateTime.Now gemacht wird weniger genau als das, was die meisten CPU-Uhren umgehen können? Vielleicht ist es nur für den kleinsten gemeinsamen Nenner CPU entworfen?

public static void Main(string[] args)
{
    var stopwatch = new Stopwatch();
    stopwatch.Start();
    for (int i=0; i<1000; i++)
    {
        var now = DateTime.Now;
        Console.WriteLine(string.Format(
            "Ticks: {0}\tMilliseconds: {1}", now.Ticks, now.Millisecond));
    }

    stopwatch.Stop();
    Console.WriteLine("Stopwatch.ElapsedMilliseconds: {0}",
        stopwatch.ElapsedMilliseconds);

    Console.ReadLine();
}
War es hilfreich?

Lösung

  

Warum DateTime.Now würde weniger gemacht werden, genau als das, was die meisten CPU-Uhren umgehen können?

Eine gute Uhr sollte beides sein präzise und genau ; diejenigen sind unterschiedlich. Wie der alte Witz geht, ist eine stehengebliebene Uhr genau genau zweimal täglich, eine Uhr langsam eine Minute nie genau, jederzeit. Aber die Uhr langsam eine Minute ist immer genau auf die nächste Minute, während eine stehengebliebene Uhr keine nützliche Präzision überhaupt hat.

Warum sollte die Datetime sein präzise , eine Mikrosekunde zu sagen, wenn es nicht möglich sein kann, genau auf die Mikrosekunde? Die meisten Menschen haben keine Quelle für offizielle Zeitsignale, die auf die Mikrosekunde genau sind. Daher sechs Stellen nach dem Komma des Gebens Genauigkeit , die letzten fünf davon sind Müll wäre liegend .

Denken Sie daran, ist der Zweck der Datetime Datum und Uhrzeit stellen . Hochpräzise Timings ist überhaupt nicht der Zweck der Datetime; wie Sie beachten, ist, dass der Zweck der Stoppuhr. Der Zweck ist es, ein Datetime Datum und Uhrzeit für Zwecke darzustellen wie die aktuelle Zeit für den Benutzer, die Berechnung der Anzahl der Tage bis zum nächsten Dienstag, und so weiter.

Kurz gesagt, „Wie spät ist es?“ und „Wie lange das dauern?“ ganz andere Fragen sind; kein Werkzeug verwenden, entwickelt, um eine Frage zu beantworten, den anderen zu beantworten.

Danke für die Frage; Das wird ein guter Blog-Artikel machen! : -)

Andere Tipps

Datetime Präzisions ist etwas spezifisch für das System auf laufen gelassen wird. Die Genauigkeit wird auf die Geschwindigkeit einer Kontextwechsel im Zusammenhang, die sich um 15 oder 16 ms zu sein tendiert. (Auf meinem System, es ist tatsächlich etwa 14 ms von meinen Tests, aber ich habe einige Laptops gesehen, wo es näher an 35-40 ms Genauigkeit.)

schrieb Peter Bromberg einem Artikel auf hoher Präzision Code-Timing in C #, die in diesem diskutiert .

Ich möchte eine präzise Datetime.Now :), so dass ich diese bis gekocht:

public class PreciseDatetime
{
    // using DateTime.Now resulted in many many log events with the same timestamp.
    // use static variables in case there are many instances of this class in use in the same program
    // (that way they will all be in sync)
    private static readonly Stopwatch myStopwatch = new Stopwatch();
    private static System.DateTime myStopwatchStartTime;

    static PreciseDatetime()
    {
        Reset();

        try
        {
            // In case the system clock gets updated
            SystemEvents.TimeChanged += SystemEvents_TimeChanged;
        }
        catch (Exception)
        {                
        }
    }

    static void SystemEvents_TimeChanged(object sender, EventArgs e)
    {
        Reset();
    }

    // SystemEvents.TimeChanged can be slow to fire (3 secs), so allow forcing of reset
    static public void Reset()
    {
        myStopwatchStartTime = System.DateTime.Now;
        myStopwatch.Restart();
    }

    public System.DateTime Now { get { return myStopwatchStartTime.Add(myStopwatch.Elapsed); } }
}

MSDN dass DateTime.Now finden hat eine ungefähre Auflösung von 10 Millisekunden auf allen NT-Betriebssystemen.

Die tatsächliche Genauigkeit ist hardwareabhängig. Bessere Genauigkeit kann mit Hilfe erhalten QueryPerformanceCounter .

Für das, was es wert ist, kurz tatsächlich die .NET Quelle Überprüfung bereitgestellt Eric Lippert einen Kommentar auf diese Frage SO sagen, dass Datetime nur genau auf ca. 30 ms ist. Die Argumentation für nicht seine Nanosekunde genau, in seinen Worten, dass es „nicht sein müssen.“

Von MSDN-Dokumentation :

  

Die Auflösung dieser Eigenschaft   ist abhängig von den System-Timer.

Sie behaupten auch, dass die ungefähre Auflösung unter Windows NT 3.5 und höher 10 ms ist:)

  

Die Auflösung dieser Eigenschaft ist abhängig von den System-Timer, die   ist abhängig von dem zugrunde liegenden Betriebssystem. Es neigt dazu, zu sein zwischen 0,5   und 15 Millisekunden.

Als Ergebnis wiederholte Aufforderungen an die Jetzt-Eigenschaft in einem kurzen Zeitintervall, wie in einer Schleife, können den gleichen Wert zurück.

MSDN Link-

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top