首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >精确跟踪时间的方法

精确跟踪时间的方法
EN

Stack Overflow用户
提问于 2013-10-09 12:25:04
回答 1查看 1.2K关注 0票数 0

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

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

  • 用户更改其系统时间。
  • 操作系统NTP服务器更新本地时间
  • ..。

所以实际上我们有一个"TimeProvider",它为整个应用程序提供了当前的时间。

我们的目标是检测是否发生时移,并平稳地纠正我们的本地时间(比如,如果我们有一个小时的“时间跳跃”,那么每秒钟纠正100 is,直到完全纠正为止)。

这里基本上是我要提供的时间(请注意,目前我绝对没有平稳的时间变化,但不是我当前的问题)

代码语言:javascript
复制
internal class TimeChange : IDisposable
{
    private readonly Timer _timer;
    private readonly Stopwatch _watch = new Stopwatch();
    private DateTime _currentTime;

    public DateTime CurrentTime 
    {
        get { return _currentTime + _watch.Elapsed; }
    }

    public TimeChange()
    {
        _timer = new Timer(1000);
        _timer.Elapsed += OnTimerElapsed;
        _timer.Start();
        _watch.Start();
        _currentTime = DateTime.UtcNow;
    }

    public void Dispose()
    {
        _timer.Stop();
        _timer.Elapsed -= OnTimerElapsed;
    }

    private void OnTimerElapsed(object sender, ElapsedEventArgs e)
    {
        DateTime currentTime = DateTime.UtcNow;
        TimeSpan timeDerivation = currentTime - _currentTime - _watch.Elapsed;
        _watch.Restart();
        _currentTime = currentTime;
        Console.WriteLine("Derivation: " + timeDerivation.TotalMilliseconds + "ms");
    }
}

但是当我做一些测试时,我注意到即使在我的本地时间没有做任何事情,我也有不同之处。差别不大(<1ms),但仍然是:

代码语言:javascript
复制
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

这是1秒的推导,如果我把1000毫秒替换成10000毫秒,我很快就会得到1ms到0.5ms之间的时间推导。

所以我的问题(最后:P):

  1. 为什么两个Utc.DateTime给了我这么多的差异?它们都是以时钟滴答为基础的,不是吗?
  2. 难道没有办法更精确地实现这一时间轮班吗?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-09 12:33:57

  1. 不,它们都不是基于时钟滴答。Stopwatch可能是高或低分辨率。如果res较低,则使用DateTime.UtcNow底面。很偶然,你不能选择高还是低,所以:
  2. 创建自己的“秒表”,它总是使用DateTime.UtcNow底盘。

编辑

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

1.更详细地说:

Stopwatch使用这种方法:

代码语言:javascript
复制
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似乎是不可设置的,并且作为一个static应用于整个系统,所以编写您自己的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19271958

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档