DateTime.Now выбрасывает исключение

Я получаю исключение, заброшенное на DateTime.Now на нашем сервере работает несколько сайтов. Это произошло сейчас дважды для меня за последние 3 дня. Действительно странно. Мне интересно, началось ли это с последнего обновления Windows, и если кто-то из вас видел подобное поведение.

Исключение составляет:

BASE EXCEPTION:
  TYPE: System.ArgumentOutOfRangeException
  MESSAGE: Value to add was out of range.
Parameter name: value
  STACK TRACE:
   at System.DateTime.Add(Double value, Int32 scale)
   at System.TimeZoneInfo.TransitionTimeToDateTime(Int32 year, TransitionTime transitionTime)
   at System.TimeZoneInfo.GetDaylightTime(Int32 year, AdjustmentRule rule)
   at System.TimeZoneInfo.GetIsDaylightSavingsFromUtc(DateTime time, Int32 Year, TimeSpan utc, AdjustmentRule rule, Boolean& isAmbiguousLocalDst)
   at System.TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc(DateTime time, Boolean& isAmbiguousLocalDst)
   at System.DateTime.get_Now()
   at (my code).FrontEnd.FrontEndPage.Page_Load(Object sender, EventArgs e) in (my code file)\code\presentation\FrontEndPage.cs:line 118
   at (my code).purchase.Page_Load(Object sender, EventArgs e) in (my code file)\purchase.aspx.cs:line 94
   at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
   at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
   at System.Web.UI.Control.OnLoad(EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Код, где это происходит, - это первая строка в if-statement:

HttpCookie loggedIn = Request.Cookies[Config.Instance.LoggedInCookieName];
if (loggedIn != null)
{
    loggedIn.Expires = DateTime.Now.AddHours(4);
    Response.Cookies.Add(loggedIn);
}

Хотя там есть AddHours и исключение говорит о DateTime.Add, я не думаю, что это имеет какое-либо отношение к AddHours, но вызвано вызовом Now, как вы можете видеть в трассировке стека.

Сервер, на котором я работаю, работает под управлением Windows Server 2003 и работает на английском языке (Великобритания).

Спасибо за любую помощь.

Ответ 1

Просмотр кода в Reflector, ваше исключение происходит, когда in-lined AddDays получает плохие данные в TransitionTimeToDateTime.

Оба вхождения процесса AddDays transitionTime.DayOfWeek, где transitionTime - rule.DaylightTransitionStart или rule.DaylightTransitionEnd из GetDaylightTime (а также time.DayOfWeek, но это всегда Mod 7).

Это означает, что GetTimeZoneInformation иногда возвращает плохие данные, где AdjustmentRule генерируется в GetOneYearLocalFromUtc, который вызывает GetCurrentOneYearLocal.

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

<суб > Обратите внимание, что эта информация не кэшируется и извлекается каждый раз, когда вы вызываете DateTime.Now (это, конечно, правильная вещь, которую можно было бы изменить, если бы DST мог просто измениться, или пользователь мог изменить текущий часовой пояс), хороший повод для некоторых преждевременную оптимизацию, максимально используя DateTime.UtcNow и применяя .ToLocalTime только тогда, когда вам нужно отобразить время для пользователя. Суб >

Ответ 2

Это может быть вызвано DateTime.Now не является потокобезопасным (что, я считаю, будет ошибкой). Я слышал о некоторых версиях .net, имеющих эту ошибку. Это не обязательно поможет обернуть вашу строку кода в блокировку, потому что все вызовы DateTime.Now должны быть обработаны аналогичным образом. В качестве обходного пути я бы рекомендовал делать то, что сделал человек в подобном вопросе, - заманить исключение, созданное DateTime.Now и попробовать второй раз.

Можете ли вы написать небольшое тестовое приложение, которое вызывает DateTime.Now много раз на несколько потоков, чтобы заставить его и проверить, является ли это причиной?

Какая версия .Net используется этими веб-сайтами?