DateTime.Now导致IO阻塞?

Dan*_*ing 3 c#

在一次会议上,有人告诉我DateTime.Now导致IO阻塞,这是我从未停止过的事情.如果是的话,为什么?

Tig*_*ran 5

好吧,考虑到这一点

使用ILSpymscorelib我们可以发现,这DateTime.Now,似乎以这种方式:

public static DateTime Now
{
    get
    {
        DateTime utcNow = DateTime.UtcNow;
        bool isAmbiguousDst = false;
        long ticks = TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc(utcNow, out isAmbiguousDst).Ticks;
        long num = utcNow.Ticks + ticks;
        if (num > 3155378975999999999L)
        {
            return new DateTime(3155378975999999999L, DateTimeKind.Local);
        }
        if (num < 0L)
        {
            return new DateTime(0L, DateTimeKind.Local);
        }
        return new DateTime(num, DateTimeKind.Local, isAmbiguousDst);
    }
}
Run Code Online (Sandbox Code Playgroud)

该功能GetDateTimeNowUtcOffsetFromUtc如下所示:

internal static TimeSpan GetDateTimeNowUtcOffsetFromUtc(DateTime time, out bool isAmbiguousLocalDst)
{
    isAmbiguousLocalDst = false;
    TimeZoneInfo.OffsetAndRule oneYearLocalFromUtc = TimeZoneInfo.GetOneYearLocalFromUtc(time.Year);
    TimeSpan timeSpan = oneYearLocalFromUtc.offset;
    if (oneYearLocalFromUtc.rule != null)
    {
        bool isDaylightSavingsFromUtc = TimeZoneInfo.GetIsDaylightSavingsFromUtc(time, time.Year, oneYearLocalFromUtc.offset, oneYearLocalFromUtc.rule, out isAmbiguousLocalDst);
        timeSpan += (isDaylightSavingsFromUtc ? oneYearLocalFromUtc.rule.DaylightDelta : TimeSpan.Zero);
    }
    return timeSpan;
}
Run Code Online (Sandbox Code Playgroud)

GetOneYearLocalFromUtc 而是看起来像:

private static TimeZoneInfo.OffsetAndRule GetOneYearLocalFromUtc(int year)
{
    if (TimeZoneInfo.s_oneYearLocalFromUtc == null || TimeZoneInfo.s_oneYearLocalFromUtc.year != year)
    {
        TimeZoneInfo currentOneYearLocal = TimeZoneInfo.GetCurrentOneYearLocal();
        TimeZoneInfo.AdjustmentRule rule = (currentOneYearLocal.m_adjustmentRules == null) ? null : currentOneYearLocal.m_adjustmentRules[0];
        TimeZoneInfo.s_oneYearLocalFromUtc = new TimeZoneInfo.OffsetAndRule(year, currentOneYearLocal.BaseUtcOffset, rule);
    }
    return TimeZoneInfo.s_oneYearLocalFromUtc;
}
Run Code Online (Sandbox Code Playgroud)

最后GetCurrentOneYearLocal看起来像:

private static TimeZoneInfo GetCurrentOneYearLocal()
{
    Win32Native.TimeZoneInformation timeZoneInformation = default(Win32Native.TimeZoneInformation);
    long num = (long)UnsafeNativeMethods.GetTimeZoneInformation(out timeZoneInformation);
    TimeZoneInfo result;
    if (num == -1L)
    {
        result = TimeZoneInfo.CreateCustomTimeZone("Local", TimeSpan.Zero, "Local", "Local");
    }
    else
    {
        result = TimeZoneInfo.GetLocalTimeZoneFromWin32Data(timeZoneInformation, false);
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

有趣的功能GetTimeZoneInformation,存在kernel32.dll于文档中描述如下:

检索当前时区设置.这些设置控制协调世界时(UTC)和本地时间之间的转换.

要访问该时间信息,Windows实际上使用IO访问权限.不确定这是否可以被定义为"阻塞",但它绝对是保存在磁盘上的系统信息,至少是它的一部分.