Подтвердить что ты не робот

Кэш-ключ вызывает ошибку. "Отрицание минимального значения номера дополнительного номера недействительно".

Это одна из самых странных ошибок, которые я когда-либо видел.

Я делаю очень простой вызов для возврата значений из кеша HttpRuntime. Вызов:

return HttpContext.Current.Cache[cacheKey];

Если он возвращает null, это отлично. Я проверяю, является ли возвращаемое значение нулевым и действует соответствующим образом. Я давно использую этот вызов.

Недавно по какой-то причине, когда cacheKey установлен на это точное значение:

"Topic_GridSelectAll:5,null,2010-08-31-20-00-00,Published,desc,5,1"

Вызывается System.OverflowException: Недопустимо отклонение минимального значения номера дополнения twos.

Ничего о вызове, связанном коде или сервере не изменилось. Если cacheKey имеет несколько разные символы, он отлично работает. Например, этот cacheKey возвращает значение null без какого-либо исключения:

"Topic_GridSelectAll:5,null,2010-08-31-21-00-00,Published,desc,5,1"

Обратите внимание, что единственная разница между этими двумя строками - это символы времени: 2010-08-31-20-00-00 по сравнению с 2010-08-31-21-00-00.

Почему, черт возьми, это имеет значение? И почему теперь после всего этого времени?

Трассировка стека:

[OverflowException: Negating the minimum value of a twos complement number is invalid.]
   System.Math.AbsHelper(Int32 value) +12753486
   System.Web.Caching.CacheMultiple.UpdateCache(CacheKey cacheKey, CacheEntry newEntry, Boolean replace, CacheItemRemovedReason removedReason, Object& valueOld) +142
   System.Web.Caching.CacheInternal.DoGet(Boolean isPublic, String key, CacheGetOptions getOptions) +122
   MyProject.Helpers.CacheHelper.GetData(String cacheDomain, String cacheKey) in ...

Я попытался изменить вызов кеша вместо HttpRuntime.Cache(т.е. HttpRuntime.Cache[cacheKey]), но это не имело никакого значения. Я знаю, что это тот же базовый поставщик кеша, но я подумал, что, может быть, другой звонок изменит ситуацию. Нет кубиков.

4b9b3361

Ответ 1

Похоже, на вашей платформе GetHashCode() (в System.String) для этой точной строки возвращается -2147483648. Вы можете проверить это (как я), вставив эту строку и просто вызвав ее GetHashCode(). Каждая строка получает хеш-код, и это один. И что? хорошо....

CacheMultiple.UpdateCache вызывает GetHashCode() в вашей ключевой строке, затем вызывает GetCacheSingle(), который вызывает Math.Abs, который в итоге вызывает AbsHelper. AbsHelper выдает исключение, если число точно равно -2147483648! (так как значение absoulte было бы больше, чем максимальное значение, которое можно удерживать)

Итак, поздравляю, вы выиграли лотерею GetHashCode - из 2 ^ 32 возможных значений, вы получили право (ну, неправильно). К сожалению, кажется, что внутренности Web.Cache не обрабатывают это вообще, поэтому вам нужно было бы вызвать GetHashCode в своей строке, чтобы узнать, равно ли она равным -2147483648, и если это так немного изменит строку. Или, ловушка для этого исключения - и если он пойман, повторите попытку, слегка изменив свой ключ (предсказуемым образом, чтобы снова воссоздать его снова).

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