如何在C#中获得精确的DateTime

时间:2013-08-15 17:16:20

标签: c# datetime

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

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

问题是:如何以比DateTime.UtcNow提供的更精确的方式获得当前日期/时间?

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

3 个答案:

答案 0 :(得分:9)

您可以使用Stopwatch进行更精确的时间测量。然后,您可以让每个日志条目记录从第一个操作开始的时间。如果它很重要,你可以记录第一个操作的DateTime,从而计算剩下的时间,但是听起来就像是第一个操作开始后的滴答/纳秒就足够了。

答案 1 :(得分:4)

如果要添加跟踪,可以编写自己的ETW跟踪提供程序,如here。那么你不需要注意如何获取时间。 Windows内核会关注时间是否准确以及事件的顺序是否正确。

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

使用ETW事件时,您可以使用Windows Performance Toolkit免费获得功能强大的跟踪分析器。作为额外的奖励,您可以在所有流程中进行系统范围的分析,同时影响最小。

这允许您有选择地为您编写的每个事件添加调用堆栈,当您想要追踪谁调用您的Dispose方法两次时,这可能是非常宝贵的。

enter image description here

答案 2 :(得分: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);

最后一个变体用作基础DateTime.UtcNow,但每次调用如果没有更改,则将其递增1。