C# 日期时间。现在导致IO阻塞? 在一个会议上有人告诉我DATETIME.现在导致IO阻塞,这是我从来没有停止考虑过的事情。如果是,为什么?
如果您使用类似于反射镜的工具DateTime查看源代码。现在调用Win API,然后使用该工具创建新的DateTime对象,该对象自0001年1月1日00:00:00.000起具有一个带刻度的int64参数。这里没有看到任何可能导致I/O阻塞的内容,GetSystemTimeAsFileTime文档中也没有提到这一点 使用C# 日期时间。现在导致IO阻塞? 在一个会议上有人告诉我DATETIME.现在导致IO阻塞,这是我从来没有停止考虑过的事情。如果是,为什么?,c#,C#,如果您使用类似于反射镜的工具DateTime查看源代码。现在调用Win API,然后使用该工具创建新的DateTime对象,该对象自0001年1月1日00:00:00.000起具有一个带刻度的int64参数。这里没有看到任何可能导致I/O阻塞的内容,GetSystemTimeAsFileTime文档中也没有提到这一点 使用mscorelib我们可以发现,DateTime.Now,以以下方式显示: public static DateTime Now { get {
mscorelib
我们可以发现,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);
}
}
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;
}
最后,GetCurrentOneYearLocal
显示如下:
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;
}
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;
}
有趣的函数是GetTimeZoneInformation
,出现在kernel32.dll
中,文档中描述了该函数,如:
检索当前时区设置。这些设置控制
协调世界时(UTC)和当地时间之间的转换
要访问该时间信息,Windows实际上使用
IO
access。不确定这是否可以定义为“阻塞”,但它肯定是在访问保存在磁盘上的系统信息,至少是其中的一部分。到目前为止,还没有人回答当前时间的真正来源。我不了解最新的PC架构。但几年前,它还是CPU(南桥)外部芯片的一部分。所以为了得到时间,你必须用芯片做一些I/O操作。(这不是磁盘访问,而是I/O操作。)
由于当前进程必须等待时钟的响应,因此它阻塞了I/O
所以会议上的那个人是对的。我可以问一下,为什么你没有问告诉你的人?奇怪的是,为什么这个问题得到这么多的赞成票,而背景信息却这么少。我的下一个问题:“我听说太多的stackoverflow异常会导致计算机崩溃,如果真的发生了,为什么?”,这是一个具有挑衅性的问题。会议的主题是什么。总的来说是净的吗?Windows phone?新华社?这是我第一次听说这件事。MSDN确实说,例如,您不应该使用DateTime。现在,对于性能测试,它只是解释说,它没有很好的分辨率。我不确定这是否是一个I/O阻塞问题,因为可能会进行系统调用,因此,就像您调用I/O函数一样,你给了系统一个从你的进程中获得控制权并将其交给另一个进程的机会。无论如何,让人惊讶的是,像
DateTime这样的频繁使用的属性所发生的一切。现在
@TimSchmelter:这实际上是像我这样的人只能表达假设的问题。因为只有在Windows操作系统中实际实现这一点的人(在不同版本之间可能有所不同)才能给出准确的答案。@TimSchmelter:所以我假设它是从磁盘读取的,同时考虑到其他文档,例如,存储在注册表中的信息在哪里,所以也必须从磁盘读取。这并不意味着,con不会说不,操作系统可以在启动时将其兑现并从内存中读取(事实上,很可能是从内存映射文件中读取)。@Tigran:时区信息迟早会被缓存。但当前时间是从南桥芯片(或其等效芯片)检索的,需要阻塞I/O。因此真正有趣的部分不在.NET代码中,但是在GetTimeZoneInformation
@Codo:这实际上就是我的答案:)我想你错过了当前时间的真正来源:南桥芯片。要访问它,需要I/O,并且它处于阻塞状态。