簡體   English   中英

Windows系統時間,精度為毫秒

[英]Windows system time with millisecond precision

與我之前的問題相關 ,但是使用C#,我需要精確的系統時間,包括毫秒。

C#時間函數的准確度高達10到15毫秒,但不完全是1毫秒。

隊列性能計數器的情況也是如此。 有沒有其他方法可以將精度提高到精確毫秒?

您可以使用此DateTimePrecise類在.NET中獲得高精度時間

UPDATE
CodeProject鏈接不再有效。 已從archive.org中提取代碼並將其嵌入此處以供將來參考。 此代碼“按原樣”包含在此處,與CodeProject頁面中包含的方式完全相同。

DateTimePrecise是那么容易,因為使用DateTime.Now ,除了DateTimePrecise.Now是一個實例方法,而不是一個靜態方法,所以你必須首先實例化一個DateTimePrecise

using System.Diagnostics;

/// DateTimePrecise provides a way to get a DateTime that exhibits the
/// relative precision of
/// System.Diagnostics.Stopwatch, and the absolute accuracy of DateTime.Now.
public class DateTimePrecise
{
    /// Creates a new instance of DateTimePrecise.
    /// A large value of synchronizePeriodSeconds may cause arithmetic overthrow
    /// exceptions to be thrown. A small value may cause the time to be unstable.
    /// A good value is 10.
    /// synchronizePeriodSeconds = The number of seconds after which the
    /// DateTimePrecise will synchronize itself with the system clock.
    public DateTimePrecise(long synchronizePeriodSeconds)
    {
        Stopwatch = Stopwatch.StartNew();
        this.Stopwatch.Start();

        DateTime t = DateTime.UtcNow;
        _immutable = new DateTimePreciseSafeImmutable(t, t, Stopwatch.ElapsedTicks,
            Stopwatch.Frequency);

        _synchronizePeriodSeconds = synchronizePeriodSeconds;
        _synchronizePeriodStopwatchTicks = synchronizePeriodSeconds *
            Stopwatch.Frequency;
        _synchronizePeriodClockTicks = synchronizePeriodSeconds *
            _clockTickFrequency;
    }

    /// Returns the current date and time, just like DateTime.UtcNow.
    public DateTime UtcNow
    {
        get
        {
            long s = this.Stopwatch.ElapsedTicks;
            DateTimePreciseSafeImmutable immutable = _immutable;

            if (s < immutable._s_observed + _synchronizePeriodStopwatchTicks)
            {
                return immutable._t_base.AddTicks(((
                    s - immutable._s_observed) * _clockTickFrequency) / (
                    immutable._stopWatchFrequency));
            }
            else
            {
                DateTime t = DateTime.UtcNow;

                DateTime t_base_new = immutable._t_base.AddTicks(((
                    s - immutable._s_observed) * _clockTickFrequency) / (
                    immutable._stopWatchFrequency));

                _immutable = new DateTimePreciseSafeImmutable(
                    t,
                    t_base_new,
                    s,
                    ((s - immutable._s_observed) * _clockTickFrequency * 2)
                    /
                    (t.Ticks - immutable._t_observed.Ticks + t.Ticks +
                        t.Ticks - t_base_new.Ticks - immutable._t_observed.Ticks)
                );

                return t_base_new;
            }
        }
    }

    /// Returns the current date and time, just like DateTime.Now.
    public DateTime Now
    {
        get
        {
            return this.UtcNow.ToLocalTime();
        }
    }

    /// The internal System.Diagnostics.Stopwatch used by this instance.
    public Stopwatch Stopwatch;

    private long _synchronizePeriodStopwatchTicks;
    private long _synchronizePeriodSeconds;
    private long _synchronizePeriodClockTicks;
    private const long _clockTickFrequency = 10000000;
    private DateTimePreciseSafeImmutable _immutable;
}

internal sealed class DateTimePreciseSafeImmutable
{
    internal DateTimePreciseSafeImmutable(DateTime t_observed, DateTime t_base,
         long s_observed, long stopWatchFrequency)
    {
        _t_observed = t_observed;
        _t_base = t_base;
        _s_observed = s_observed;
        _stopWatchFrequency = stopWatchFrequency;
    }
    internal readonly DateTime _t_observed;
    internal readonly DateTime _t_base;
    internal readonly long _s_observed;
    internal readonly long _stopWatchFrequency;
}

Windows不希望通過每秒更新系統時鍾1000次來浪費電力,因此默認情況下每秒僅更新60-100次。 如果將多媒體定時器設置為1ms,則可以從時鍾獲得1ms的分辨率,但不建議這樣做。

為了進一步詳細說明節電,當CPU空閑一段時間后會發生的事情是它可以進入一個非常低功耗的狀態。 每當它被中斷時(例如,增加時鍾滴答),它必須離開其非常低功率狀態並使用大量電力為整個CPU供電以服務該中斷。 換句話說,額外的功率不是遞增時鍾滴答,而是讓CPU保持清醒狀態。

由於我的筆記本電腦在時鍾頻率為60Hz時空閑時使用10W,而在1000Hz時使用11W,我的電池續航時間為300分鍾,這個較慢的時鍾給了我近30分鍾的電池續航時間!

嘗試使用System.Diagnostics.Stopwatch進行高分辨率計時。

如果安裝的硬件和操作系統支持高分辨率性能計數器,則Stopwatch類使用該計數器來測量經過的時間。 否則,Stopwatch類使用系統計時器來測量經過的時間。

嘗試使用原生DateTime.Ticks ,系統時間精度可達100納秒; 1毫秒= 10000蜱。

while (true)
{
    System.Threading.Thread.Sleep(1);

    Console.WriteLine("{0} {1}",
        System.DateTime.Now.Ticks,
        System.DateTime.Now.ToString("ss:fff"));
}

PS > .\test.exe
    634134152924322129 52:432
    634134152924332129 52:433
    634134152924342130 52:434
    634134152924352130 52:435
    634134152924362131 52:436
    634134152924372131 52:437
    634134152924382132 52:438
    634134152924392133 52:439
    634134152924402133 52:440
    634134152924412134 52:441
    634134152924422134 52:442
    634134152924432135 52:443

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM