.net – Cache.Add绝对到期 – 是否基于UTC?

Cache.Add的示例使用DateTime.Now.Add来计算到期时间,即它通过:
DateTime.Now.AddSeconds(60)

作为absoluteExpiration参数的值。

我想过,相对于DateTime.UtcNow计算会更正确[因为如果夏令时开始在从现在到到期点之间的间隔时间,没有歧义]。

在介绍DateTimeKind之前,我已经猜到,在缓存管理中有一些丑陋的黑客,如果时间不是UTC时间,它会做一些适当的事情。

在.NET 2.0和更高版本中,我猜测它应该处理DateTime.UtcNow.AddSeconds(60)计算的DateTime,因为它有DateTime.Kind在其推理中用作输入。

我已经自信地使用DateTime.UtcNow作为基础多年,但是没能提出一个理由,这是绝对正确的事情,没有任何东西指出文件已被高度误导4年。

问题?

>尽管有很多bingage和谷歌我没有能够找到任何权威的讨论,从MS – 任何人都可以找到一些关于这一点?
>有什么原因为什么使用UtcNow不会更正确和/或安全?

(是的,我可以细读源和/或反射器的来源,但我正在寻找一个完整的吹一吹下来!)

解决方法

reported this bug on Microsoft Connect一段时间前,但它已被关闭,将不会解决

如果您在本地时间指定绝对到期,您仍然有一个.NET 2.0中的问题。

在夏令时结束时的一小时内,您的当地时间不明确,因此您可能会得到意想不到的结果,即绝对到期时间可能比预期长一个小时。

在欧洲,夏令时在2009年10月25日的02:00结束。下面的示例说明如果您在01:59将项目放置在缓存中,且过期时间为2分钟,则该项目将在缓存中保留一小时, 2分钟。

DateTime startTime = new DateTime(2009,10,25,1,59,0);
DateTime endTime = startTime.AddMinutes(2);
// end time is two minutes after start time

DateTime startUtcTime = startTime.ToUniversalTime();
DateTime endUtcTime = endTime.ToUniversalTime();
// end UTC time is one hour and two minutes after start UTC time

Console.WriteLine("Start UTC time = " + startUtcTime.ToString());
Console.WriteLine("End UTC time = " + endUtcTime.ToString());

.NET 2.0或更高版本的解决方法是指定Ruben指出的UTC中的绝对到期时间。

微软应该建议使用UTC的绝对到期的例子,但我想有可能混乱,因为这个建议只适用于.NET 2.0和更高版本。

编辑

评论

But the exposure only occurs if the
conversion happens during the overlap.
The single conversion actually taking
place is when you lodge the item with
Cache.Add

该问题只会发生,如果您在缓存中插入一个项目AbsoluteExpiration时间在本地时间在一个模糊的小时在夏令时结束时。

例如,如果您的本地时区是中欧(冬季GMT 1,夏季GMT 2),并且您在2009年10月25日01:59:00执行以下代码

DateTime absoluteExpiration = DateTime.Now.AddMinutes(2);
Cache.Add(... absoluteExpiration ...)

那么项目将保留在缓存中一小时两分钟,而不是通常预期的两分钟。这对于一些高度时间关键的应用(例如股票行情,航空公司出发板)来说可能是个问题。

这里发生的是(假设欧洲时间,但原则是相同的任何时区):

> DateTime.Now = 2009-10-25 01:59:00 local。 local = GMT 2,因此UTC = 2009-10-24 23:59:00
> .AddMinutes(2)= 2009-10-25 02:01:00 local。 local = GMT 1,因此UTC = 2009-11-25 01:01:00
> Cache.Add内部将到期时间转换为UTC(2009-11-25 01:01:00),因此到期时间比当前UTC时间(23:59:00)提前一小时两分钟。

如果您使用DateTime.UtcNow代替DateTime.Now,缓存过期将是两分钟(.NET 2.0或更高版本):

DateTime absoluteExpiration = DateTime.UtcNow.AddMinutes(2);
Cache.Add(... absoluteExpiration ...)

评论

Or am I missing something?

不你不是。您的分析是现货,如果您的应用程序是时间关键的,并在DST期间的这段时间运行,你是正确的使用DateTime.UtcNow

Ruben的回答中的陈述:

you’re safe to use either as long as the Kind on the time you supply is set

是不正确的。

相关文章

这篇文章主要讲解了“WPF如何实现带筛选功能的DataGrid”,文...
本篇内容介绍了“基于WPF如何实现3D画廊动画效果”的有关知识...
Some samples are below for ASP.Net web form controls:(fr...
问题描述: 对于未定义为 System.String 的列,唯一有效的值...
最近用到了CalendarExtender,结果不知道为什么发生了错位,...
ASP.NET 2.0 page lifecyle ASP.NET 2.0 event sequence cha...