7

我知道它DateTime.UtcNow没有相对较高的精度(10-15 ms 分辨率)。

这对我来说是个问题,因为在我的日志文件中,我想要更好的分辨率来解决竞争条件。

问题是:我怎样才能以比DateTime.UtcNow提供的更好的精度获得当前日期/时间?

到目前为止,我看到的唯一解决方案是:https ://stackoverflow.com/a/15008836/270348 。这是解决问题的合适方法吗?

4

3 回答 3

10

您可以使用Stopwatch更精确的时间测量。然后,您可以让每个日志条目记录从第一个操作开始的时间。如果这很重要,您可以记录DateTime第一个操作的时间,从而计算其余的时间,但听起来只有第一个操作开始以来的滴答声/纳秒就足以满足您的目的。

于 2013-08-15T17:21:10.450 回答
5

如果您想添加跟踪,您可以像这里一样编写自己的 ETW 跟踪提供程序。然后你不需要关心如何获取时间。Windows 内核将确保时间准确且事件顺序正确。

如果您不想编写自己的 ETW 提供程序,您可以使用作为 Nuget 包提供的 EventSource,它也允许您从 .NET 4.0 使用它。更多信息有Vance Morrison在他的博客上。

使用 ETW 事件时,您可以通过 Windows 性能工具包免费获得功能强大的跟踪分析器。作为额外的好处,您可以在所有进程中进行系统范围的分析,并且影响最小。

这允许您有选择地为您编写的每个事件添加调用堆栈,这在您想要跟踪谁确实调用了您的 Dispose 方法两次时非常有用。

在此处输入图像描述

于 2013-08-15T17:42:15.050 回答
2

您真的需要一个精确的计时器,还是您真正需要的是可以提供某种功能的东西?例如:

static class AutoIncrement
{
    private static long num;

    public static long Current
    {
        get
        {
            return Interlocked.Increment(ref num);
        }
    }
}

Console.WriteLine(AutoIncrement.Current);
Console.WriteLine(AutoIncrement.Current);
Console.WriteLine(AutoIncrement.Current);
Console.WriteLine(AutoIncrement.Current);
Console.WriteLine(AutoIncrement.Current);

这保证是唯一的,并且每次都改变,并且被排序。它的精度优于微秒。它的精度在单台 PC 上是绝对的。

或者如果你真的想要时间戳......

static class AutoIncrement
{
    private static long lastDate;

    public static DateTime Current
    {
        get
        {
            long lastDateOrig, lastDateNew;

            do
            {
                lastDateOrig = lastDate;

                lastDateNew = lastDateOrig + 1;

                lastDateNew = Math.Max(DateTime.UtcNow.Ticks, lastDateNew);
            }
            while (Interlocked.CompareExchange(ref lastDate, lastDateNew, lastDateOrig) != lastDateOrig);

            return new DateTime(lastDateNew, DateTimeKind.Utc);
        }
    }
}

DateTime ac = AutoIncrement.Current;
Console.WriteLine(CultureInfo.InvariantCulture, "{0} {1:yyyy/MM/dd HH:mm:ss.fffffff}", ac.Ticks, ac);

最后一个变体用作 base DateTime.UtcNow,但每次调用如果未更改,则将其递增一。

于 2013-08-15T17:25:54.143 回答