Кэш. Добавить абсолютное истечение - базирующийся UTC или нет?

Динамический материал звучит прохладным , если Вам нужен он , но я не ожидаю использовать его очень часто.

универсальное различие для делегатов и интерфейсов подобно - отсутствие различия является головной болью в данный момент, но многие места, где это - боль, не будут покрыты ограниченным различием, доступным в C# 4.

функции COM особенно не интересуют меня - я действительно должен надеть больше дескриптора, каковы они все же.

Дополнительные и именованные параметры могли иметь большое значение при создании неизменных типов: это включает синтаксис как:

Person p = new Person (name: "Jon", age: 32);

, не имея гигантских комбинаций перегрузок конструктора. Я предпочел бы немного больше поддержки записи неизменных типов в форме автоматически реализованных свойств только для чтения, но я не ожидаю, что мы получим тех. (Они, конечно, не находятся в предложенном списке функций в данный момент.)

я лично на самом деле более интересуюсь несколькими платформа функции.NET 4.0 - в особенности , контракты и кода параллельны расширениям .

35
задан Ruben Bartelink 7 November 2009 в 13:48
поделиться

3 ответа

Я некоторое время назад сообщил об этой ошибке в 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 и более поздних версий.

EDIT

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

Но раскрытие происходит только в том случае, если преобразование происходит во время перекрытия. Единственное преобразование, фактически занимающее место - это когда вы кладете предмет с Cache.Add

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

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

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

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

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

  • DateTime .Now = 25-10-2009, 01:59:00 по местному времени. 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 ...)

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

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

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

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

вы ' Вы можете безопасно использовать любой из них, если в указанном вами времени установлен неверный тип

.

00), поэтому срок действия на один час и две минуты опережает текущее время в формате UTC (23:59:00).

Если вы используете DateTime.UtcNow вместо DateTime.Now, срок действия кеша будет составлять две минуты (. NET 2.0 или новее):

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

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

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

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

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

вы ' Вы можете безопасно использовать любой из них, если в указанном вами времени установлен неправильный Тип

.

00), поэтому срок действия на один час и две минуты опережает текущее время в формате UTC (23:59:00).

Если вы используете DateTime.UtcNow вместо DateTime.Now, срок действия кеша будет составлять две минуты (. NET 2.0 или новее):

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

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

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

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

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

вы ' Вы можете безопасно использовать любой из них, если в указанном вами времени установлен неправильный Тип

.

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

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

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

вы ' Вы можете безопасно использовать любой из них, если в указанном вами времени установлен неправильный Тип

.

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

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

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

вы ' Вы можете безопасно использовать любой из них, если в указанном вами времени установлен неправильный Тип

.

23
ответ дан 27 November 2019 в 15:44
поделиться

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

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

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

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

6
ответ дан 27 November 2019 в 15:44
поделиться

Я не согласен с использованием таблицы поиска, поскольку (для больших целых чисел) время, необходимое для ее загрузки в память, превосходит производительность обработки.

Я также использую подход побитового маскирования для Решение O (logn), которое выглядит так:

MASK = onescompliment of 0    
while SIZE is greater than 0
  SIZE = SIZE shiftRight 1
  MASK = MASK xor (MASK shiftLeft SIZE)
  output = ((output shiftRight  SIZE) bitwiseAnd MASK) bitwiseOR ((onescompliment of MASK) bitwiseAnd (output shfitLeft SIZE))

Преимущество этого подхода в том, что он обрабатывает размер вашего целого числа в качестве аргумента

в php это может выглядеть так:

function bitrev($bitstring, $size){

  $mask = ~0;
  while ($size > 0){

    $size = $size >> 1;
    $mask = $mask ^ ($mask << $size);
    $bitstring = (($bitstring >> $size) & $mask) | ((~$mask) & ($bitstring << $size));
  }
}

если я где-то не испортил свой php: (

Теперь или UtcNow ]. [См. Комментарии и ответ Джо для полного обоснования] Определенно предпочитаю UtcNow как двусмысленность на 1 час переключения на летнее время.

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

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

    РЕДАКТИРОВАТЬ: Из комментариев Джо я понимаю, что я не назвал явно тот факт, что определенно более корректно использовать UtcNow при использовании 2.0 или новее как один подвергается риску кэширования объекта на дополнительный час во время перехода на летнее время » час сурка ». Я также думаю, что документ MS должен указать на этот факт (с оговоркой, что они должны упомянуть, что это не относится к 1.1 [независимо от того, помечена ли страница как 2.0+]. Спасибо, Джо.

    EDIT: Noda У Time будет аккуратная обертка, чтобы сделать это надежным: D

    3
    ответ дан 27 November 2019 в 15:44
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: