【问题标题】:Datetime Granularity between 32bit and 64bit Windows32 位和 64 位 Windows 之间的日期时间粒度
【发布时间】:2011-12-11 14:33:28
【问题描述】:

我为一些网络调试创建了一个小型工程应用程序。它需要一个 IP 地址列表并 ping 它们,用户设置超时和速率。它记录平均往返时间,每次发送失败时,它都会记录失败的持续时间和发生时间的时间戳......

就是这样。我在带有 .Net4 的 Win7 机器上开发了它,并且不得不将它放在一组 XP 笔记本电脑上。

问题是测试期间我的盒子上的持续时间值显示不错的毫秒持续时间,在 XP 盒子上,当我看时它们显示 0 或 15.625(幻数?)......并且在字符串中有有趣的方形盒子符号?

    public void LinkUp()
    {
        if (_isLinkUp) return;

        _upTime = DateTime.Now;
        var span = _upTime.Subtract(_downTime);
        _downTimeLog.Add(new LinkDown()
                            {
                                _span = span,
                                _status = _ipStatus,
                                _time = _downTime
                            });
        _isLinkUp = true;
    }

这就是记录日志的部分。 _ipStatus 是 ping 失败的原因(通常是超时)。

    _downEventLog.AppendLine("  Duration-> " + linkDownLogEvent._span.TotalMilliseconds + "ms\n");

这就是打印的部分......有人可以阐明这种明显的差异吗?

问题已得到解答,但我将在此处进行编辑以获取更多信息。

编辑:

看来区别不是Win7和WinXP的区别,而是32位和64位的区别。

Henk 指出的 32 位 Windows 系统中,系统时钟的粒度为 15-16 毫秒,这就是时间跨度小于 16 毫秒的每个值的值 15.625。

在 64 位系统中,系统调用是针对具有更精细粒度的不同方法集。所以在我的 x64 开发机器上,我的系统时钟具有毫秒精度!

现在,秒表通过处理器仪器使用硬件接口来记录更精细的粒度(可能不是每个处理器滴答声,但我想像这种想法的东西非常准确)。如果操作系统底层的硬件没有这种级别的检测,它将使用系统时间。所以要小心!但我猜大多数现代台式机/笔记本电脑都有这种仪器......嵌入式设备或那种性质的东西可能没有,但是据我所知,秒表类不在 Compact Framework 中(在这里你必须使用 QueryPerformanceCounter( ))。

希望这一切对您有所帮助。它对我帮助很大。

_spanStopWatch 初始化程序周围的某处:

    if (!_spanStopWatch.IsHighResolution)
    {
        throw new ThisMachineIsNotAccurateEnoughForMyLikingException("Find a better machine.");
    }

具体细节:

    public void LinkUp()
    {
        if (_isLinkUp) return;

        _spanStopWatch.Stop();
        var span = _spanStopWatch.Elapsed;
        _downTimeLog.Add(new LinkDown()
                            {
                                _span = span,
                                _status = _ipStatus,
                                _time = _downTime
                            });
        _isLinkUp = true;
    }

【问题讨论】:

  • 虽然这可能不是您问题的解决方案,但您应该使用 TotalMilliseconds.ToString() 显式转换为字符串,而不是隐式转换。
  • @Polynomial 这绝对没有必要,因为它会产生完全相同的代码。

标签: c# datetime x86-64 timespan stopwatch


【解决方案1】:

0 或 15.625(幻数?)

是的,使用 DateTime.Now 仅精确到 CPU 时间片的长度,即 15-20 毫秒,具体取决于您的硬件和操作系统版本。

使用System.Diagnostics.Stopwatch 获得更准确的计时。

【讨论】:

  • +1;那么如果您在使用Stopwatch 时遇到问题,请检查以下问题:stackoverflow.com/questions/3400254/…
  • 我已经阅读了更多内容......我认为这是粒度问题。我的开发机器是 64 位的......所以使用不同的调用,它具有更精细的粒度。
  • @Henk 你能提供秒表使用的sn-p吗?我会仔细阅读 MSDN,但有经验丰富的用户输入总是很好的!非常感谢你们。
  • 实现起来比我想象的要容易得多……太棒了。也给了我更高的准确性,我的老板会很高兴:P
猜你喜欢
  • 2010-12-18
  • 2012-01-21
  • 2012-09-03
  • 2014-08-09
  • 1970-01-01
  • 1970-01-01
  • 2011-01-28
  • 2011-05-15
  • 2017-07-29
相关资源
最近更新 更多