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 используется этими веб-сайтами?