加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

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

发布时间:2020-12-15 19:13:11 所属栏目:asp.Net 来源:网络整理
导读:Cache.Add的示例使用DateTime.Now.Add来计算到期时间,即它通过: DateTime.Now.AddSeconds(60) 作为absoluteExpiration参数的值。 我想过,相对于DateTime.UtcNow计算会更正确[因为如果夏令时开始在从现在到到期点之间的间隔时间,没有歧义]。 在介绍DateTi
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

是不正确的。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读