Вопрос

Примеры для Cache.add Использование DateTime.Now.Add Чтобы вычислить срок годности, то есть он проходит:

 DateTime.Now.AddSeconds(60)

как значение absoluteExpiration параметр.

Я бы подумал, что вычисление по сравнению с DateTime.UtcNow Было бы более правильным [так как нет двусмысленности, если дневное время экономии начинается в промежуточное время между сейчас и точкой истечения срока действия].

До введения DateTimeKind, Я бы догадался, что в управлении кешами есть некоторые уродливые хаки, чтобы сделать его что -то подходящее, если время не время UTC.

В .net 2.0, а позже, я предполагаю, что он должен справиться DateTime рассчитывается как DateTime.UtcNow.AddSeconds(60) правильно учитывая, что он имеет DateTime.Kind Использовать в качестве ввода в его выводах.

Я уверенно использовал DateTime.UtcNow Как база в течение многих лет, но не смог придумать обоснование, что это определенно правильная вещь, которую нужно делать в отсутствие чего -либо, указывающего на то, что документация очень вводит в заблуждение в течение 4+ лет.

Вопросы?

  1. Несмотря на много бингаж и гуглей, я не смог найти никакой авторитетной дискуссии об этом от MS - кто -нибудь может найти что -то об этом?
  2. Есть ли причина, по которой использование UTCNOW не будет более правильным и/или безопасным?

(Да, я мог бы просмотреть источник и/или источник отражателя, но ищу полное снижение спуска!)

Это было полезно?

Решение

я сообщил об этой ошибке на Microsoft Connect Некоторое время назад, но он был закрыт, как не исправят.

У вас все еще есть проблема в .NET 2.0, если вы указали свое абсолютное истечение в локальное время.

В течение одного часа в конце дневного времени сэкономить ваше местное время неоднозначно, так что вы можете получить неожиданные результаты, то есть абсолютное истечение может быть на час дольше, чем ожидалось.

В Европе время экономии летнего света закончилось в 02:00 25 октября 2009 года. Приведенный ниже образец показывает, что если вы поместите элемент в кэше в 01:59 с истечением 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 или более поздней, чтобы указать абсолютное время истечения срока действия в UTC, как указано Рубен.

Microsoft, возможно, должна рекомендовать использовать UTC в примерах для абсолютного срока действия, но я думаю, что есть потенциал для путаницы, поскольку эта рекомендация действительна только для .NET 2.0 и позже.

РЕДАКТИРОВАТЬ

Из комментариев:

Но воздействие происходит только в том случае, если преобразование происходит во время перекрытия. На самом деле единственное преобразование происходит, когда вы подаете элемент с помощью cache.add

Проблема произойдет только в том случае, если вы вставите элемент в кеш со временем AbsoluteExpiration в местное время в этот один неоднозначный час в конце дневного времени сэкономить.

Так, например, если ваш местный часовой пояс является центральной европейской (GMT+1 зимой, GMT+2 летом), и вы выполняете следующий код в 01:59:00 25 октября 2009 года:

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

Затем предмет останется в кеше в течение одного часа и двух минут, а не в две минуты, которые вы обычно ожидаете. Это может быть проблемой для некоторых применений с очень критическим во времени (например, аккета аккета, Совет по вылете авиакомпании).

Здесь происходит (при условии европейского времени, но принцип одинаково для любого часового пояса):

  • DateTime.now = 2009-10-25 01:59:00 локально. Local = GMT+2, SO UTC = 2009-10-24 23:59:00

  • .Addminutes (2) = 2009-10-25 02:01:00 локально. Local = GMT+1, SO UTC = 2009-11-25 01:01:00

  • Cache.Add Внутренне преобразует время истечения в UTC (2009-11-25 01:01:00), поэтому истечение составляет один час и на две минуты опережать текущее время UTC (23:59:00).

Если вы используете datetime.utcnow вместо DateTime.

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

Из комментариев:

Или я что -то упускаю?

Нет, нет. Ваш анализ находится на месте, и если ваше приложение является критическим по времени и работает в течение этого периода в конце DST, вы правы, используя DateTime.Utcnow.

Утверждение в ответе Рубена:

Вы безопасны для использования, пока не установлено время, которое вы поставляете

это неверно.

Другие советы

Cache.Add преобразует дату истечения срока действия в UTC, прежде чем хранить его.

От отражателя (я пропустил большинство параметров, чтобы облегчить чтение):

public object Add(... DateTime absoluteExpiration ...)
{
    DateTime utcAbsoluteExpiration = DateTimeUtil.ConvertToUniversalTime(absoluteExpiration);
    return this._cacheInternal.DoInsert(... utcAbsoluteExpiration ...);
}

В CacheExpires.FlushExpiredItems, utcAbsoluteExpiration сравнивается с DateTime.UtcNow. Анкет В качестве Джо отмечает в своем ответе, это вызывает неожиданное поведение, когда добавление и истечение срока действия элемента кеша охватывают конец дневного света.

Высокопроизвольная идея от ответа Джеффа Стернала, который я +1'd в неполном платеже: D

Кажется, что в 1.1 (не смотрел на 1.0, но я предполагаю, что это похоже), в отсутствие DateTime.Kind и опубликовать примеры с DateTime.Now-Потранное время, они чувствуют себя комфортно сразу же звонить ToUniversalTime() немедленно.

Следовательно...

  1. В 1.x вы получите беспорядок, если вы [пользователь API] используете DateTime.UtcNow (И есть чувствительность к DST, начинающемуся во время вызова к Cache.Add)

  2. в 2.0 [и 3.x], вы безопасны для использования, пока Kind В то время, когда вы поставляете, [что обычно было бы, если бы у вас было время от DateTime.Now или же UtcNow] [См. Комментарии и ответ Джо для полного обоснования] Определенно предпочитают UtcNow как двусмысленность в течение 1 часа переключения DST.

  3. Пример остается как есть, поэтому люди, работающие с 1.x, не вводятся в заблуждение [и люди могут продолжать притворяться, что DST-это дурацкий крайний случай: P]. [То же самое, как указал Джо], но это очень спорная позиция, так как это может привести к тому, что вещи остаются в кеше в течение дополнительного часа.

Мне все еще очень интересно услышать более подробную информацию, в том числе любую от любых пони.

РЕДАКТИРОВАТЬ: Из комментариев Джо я понимаю, что я явно не назвал тот факт, что это является Определенно более правильно в использовании UtcNow При использовании 2,0 или более позднего года, когда один подвергается риску того, что предмет кэширован в течение дополнительного часа в течение «Часа сурка». Я также думаю, что MS DOC должен указать на этот факт (с условием, что им нужно упомянуть, что это не должно применяться к 1.1 [независимо от того, отмечена ли страница.

РЕДАКТИРОВАТЬ: У Noda Time будет аккуратная обертка, чтобы сделать эту надежную: D

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top