C# 精确跟踪时间的方法

C# 精确跟踪时间的方法,c#,time,timer,duration,stopwatch,C#,Time,Timer,Duration,Stopwatch,对于我的应用程序,我必须跟踪时间变化,以“平滑”时间变化 发生系统时间更改可能有以下几个原因: 用户更改其系统时间 OS NTP服务器更新本地时间 因此,实际上我们有一个“时间提供者”,它向整个应用程序提供当前时间 我们的目标是检测是否发生时间偏移,并平稳地校正本地时间(比如,如果我们有一个1小时的“时间跳跃”,则每秒校正100毫秒,直到完全校正为止) 以下是我提供的基本时间(请注意,目前我绝对不会平滑时间变化,但不是我当前的问题) 但在做一些测试时,我注意到,即使在当地时间没有做任何事情

对于我的应用程序,我必须跟踪时间变化,以“平滑”时间变化

发生系统时间更改可能有以下几个原因:

  • 用户更改其系统时间
  • OS NTP服务器更新本地时间
因此,实际上我们有一个“时间提供者”,它向整个应用程序提供当前时间

我们的目标是检测是否发生时间偏移,并平稳地校正本地时间(比如,如果我们有一个1小时的“时间跳跃”,则每秒校正100毫秒,直到完全校正为止)

以下是我提供的基本时间(请注意,目前我绝对不会平滑时间变化,但不是我当前的问题)

但在做一些测试时,我注意到,即使在当地时间没有做任何事情,我也会有差异。差别不大(
  • 不,它们并非都基于时钟滴答声。
    Stopwatch
    可能是高分辨率或低分辨率。如果低分辨率,则在neith下使用
    DateTime.UtcNow
    。不幸的是,您无法选择它是高分辨率还是低分辨率,因此:

  • 创建自己的“秒表”,它总是在Neith下使用
    DateTime.UtcNow

  • 编辑

    在(2.)中,这是一个愚蠢的建议,你显然需要避免使用
    DateTime.UtcNow
    ,因为这正是你想要纠正的。我建议你看看滴答声,我的意思是1/10000秒,以匹配高分辨率
    秒表
    。这是因为
    TimeSpan
    仅精确到1/1000秒

    1.更详细地说:

    秒表
    使用此方法:

    public static long GetTimestamp()
    {
        if (!Stopwatch.IsHighResolution)
        {
            DateTime utcNow = DateTime.UtcNow;
            return utcNow.Ticks; //There are 10,000 of these ticks in a second
        }
        else
        {
            long num = (long)0;
            SafeNativeMethods.QueryPerformanceCounter(out num);
            return num; //These ticks depend on the processor, and
                        //later will be converted to 1/10000 of a second
        }
    }
    

    但是就像我说的,
    IsHighResolution
    似乎是不可设置的,并且作为一个
    静态的
    应用于整个系统,所以写你自己的。

    我检查了,
    StopWatch.IsHighResolution
    真的
    ,它允许我在DateTime.UtcNow和使用秒表的时间测量值之间有一点差异。但是这是预期的差异吗?是的。据我所知,
    DateTime.UtcNow
    正在查询你电脑上的时钟,
    QueryPerformanceCounter
    正在查询处理器。虽然还没有得到任何证据……但通过谷歌搜索“DateTime vs QueryPerformanceCounter”可能会找到更好的答案。
    Press enter to stop
    Derivation: -0.1367ms
    Derivation: 0.9423ms
    Derivation: 0.0437ms
    Derivation: 0.0617ms
    Derivation: 0.0095ms
    Derivation: 0.0646ms
    Derivation: -0.0149ms
    
    public static long GetTimestamp()
    {
        if (!Stopwatch.IsHighResolution)
        {
            DateTime utcNow = DateTime.UtcNow;
            return utcNow.Ticks; //There are 10,000 of these ticks in a second
        }
        else
        {
            long num = (long)0;
            SafeNativeMethods.QueryPerformanceCounter(out num);
            return num; //These ticks depend on the processor, and
                        //later will be converted to 1/10000 of a second
        }
    }