c# - La clave de caché provoca el error "La negación del valor mínimo de un número de complemento de dos no es válido".
asp.net integer (1)
Este es uno de los errores más extraños que he visto.
Estoy haciendo una llamada muy simple para devolver los valores de la memoria caché HttpRuntime. La llamada es:
return HttpContext.Current.Cache[cacheKey];
Si vuelve nulo, está bien. Verifico si el valor devuelto es nulo y actúo en consecuencia. He estado usando esta llamada durante mucho tiempo.
Recientemente, por alguna razón, cuando cacheKey se establece en este valor exacto:
"Topic_GridSelectAll:5,null,2010-08-31-20-00-00,Published,desc,5,1"
se emite una excepción System.OverflowException: no es válido negar el valor mínimo de un número de complemento de dos.
Nada acerca de la llamada, código asociado o servidor ha cambiado. Si el cacheKey tiene caracteres ligeramente diferentes, funciona perfectamente bien. Por ejemplo, este cacheKey devuelve nulo sin lanzar ninguna excepción:
"Topic_GridSelectAll:5,null,2010-08-31-21-00-00,Published,desc,5,1"
Tenga en cuenta que la única diferencia entre estas dos cadenas es el tiempo: 2010-08-31-20-00-00 en comparación con el 2010-08-31-21-00-00.
¿Por qué demonios eso haría alguna diferencia? ¿Y por qué ahora después de todo este tiempo?
La traza de pila es:
[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 ...
He intentado cambiar la llamada de caché para usar HttpRuntime.Cache en su lugar (es decir, HttpRuntime.Cache[cacheKey]
), pero eso no hizo ninguna diferencia. Sé que es el mismo proveedor de caché subyacente, pero pensé que tal vez la diferente llamada haría una diferencia. No dados.
Parece que en su plataforma, GetHashCode()
(en System.String) para esa cadena exacta está devolviendo -2147483648
. Puedes probar esto (como lo hice) colocando esa cadena y simplemente llamando a GetHashCode () para ello. Cada cadena recibe un código hash, y este es uno. ¿Y qué? bien....
CacheMultiple.UpdateCache
llama a GetHashCode()
en su cadena de clave, luego llama a GetCacheSingle()
, que llama a Math.Abs
, que finalmente llama a AbsHelper
. ¡AbsHelper lanza una excepción si el número es exactamente igual a -2147483648! (ya que el valor de absoulte sería uno más que el valor máximo que se puede mantener)
Entonces, felicidades, GetHashCode
lotería GetHashCode
: de 2 ^ 32 valores posibles, obtuviste el correcto (bueno, incorrecto). Desafortunadamente, parece que las partes internas de Web.Cache no manejan esto en absoluto, por lo que tendría que llamar a GetHashCode
en su cadena para ver si era igual a -2147483648, y si es así, altere la cadena ligeramente. O, atrape para esta excepción, y si se detecta, inténtelo de nuevo después de modificar ligeramente su clave (de manera predecible para que pueda volver a crearla de la misma manera).
Buen hallazgo de errores: es probable que continúe y coloque un error en el sitio de Connect si fuera usted ... en mi opinión, no debería ser responsabilidad de la persona que llama detectar y corregir problemas de casos de borde debido a la implementación interna decisiones