2010-09-01 16 views
18

Questo è uno degli errori più strani che abbia mai visto.La chiave della cache causa l'errore "La negazione del valore minimo di un numero di complemento twos non è valida."

Sto facendo una chiamata molto semplice per restituire i valori dalla cache HttpRuntime. La chiamata è:

return HttpContext.Current.Cache[cacheKey]; 

Se restituisce null, va bene. Controllo se il valore restituito è nullo e agisco di conseguenza. Sto usando questa chiamata da molto tempo.

Recentemente, per qualche ragione, quando cacheKey è impostato su questo valore esatto: è gettato

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

uno System.OverflowException: Negare il valore minimo di un numero complemento a due non è valido.

Nulla sulla chiamata, sul codice associato o sul server è cambiato. Se cacheKey ha caratteri leggermente diversi, funziona perfettamente. Per esempio, questo cacheKey restituisce un valore nullo senza lanciare alcuna eccezione:

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

Avviso, l'unica differenza tra questi due stringhe è i personaggi del tempo: 2010-08-31-20-00-00 contro 2010-08-31 -21-00-00.

Perché diavolo farebbe differenza? E perché ora dopo tutto questo tempo?

L'analisi dello stack è:

[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 ... 

Ho provato a cambiare la chiamata cache per utilizzare HttpRuntime.Cache invece (cioè HttpRuntime.Cache[cacheKey].), Ma che ha fatto alcuna differenza. So che è lo stesso provider di cache sottostante, ma ho pensato che forse la chiamata diversa avrebbe fatto la differenza. Niente da fare.

+3

Penso che questa sia la prima domanda "strano errore" che ho visto che in realtà era uno strano errore. :) – Guffa

risposta

17

Sembra sulla tua piattaforma, GetHashCode() (in System.String) perché quella stringa esatta sta restituendo -2147483648. Potresti testarlo (come ho fatto io) inserendo quella stringa e semplicemente chiamando GetHashCode() per questo. Ogni stringa riceve un codice hash, e questo è uno. E allora? bene ....

CacheMultiple.UpdateCache chiama GetHashCode() sulla stringa chiave, poi chiama GetCacheSingle(), che chiama Math.Abs, che alla fine chiama AbsHelper. AbsHelper genera un'eccezione se il numero è esattamente uguale a -2147483648! (poiché il valore absoulte sarebbe superiore al valore massimo che può essere tenuto)

Quindi, congratulazioni, hai vinto la lotteria GetHashCode - su 2^32 valori possibili, hai ottenuto il giusto (beh, sbagliato) . Sfortunatamente, sembra che gli interni di Web.Cache non lo gestiscano affatto, quindi dovresti chiamare lo GetHashCode sulla tua stringa per vedere se era uguale a -2147483648, e in tal caso alterare leggermente la stringa. In alternativa, intercettate questa eccezione e, se rilevati, riprovate dopo aver modificato leggermente la chiave (in modo prevedibile in modo da poterla ricreare nuovamente allo stesso modo).

Bel bug find - Probabilmente andrei avanti e mettere un bug sul sito Connect se fossi in te ... secondo me, non dovrebbe essere la responsabilità del chiamante per rilevare e correggere i problemi del caso limite a causa di decisioni di implementazione interne.

+0

Interessante. Ciò ha senso. _ "a mio avviso, non dovrebbe essere responsabilità del chiamante rilevare e correggere i problemi dei casi limite a causa di decisioni di implementazione interne." _ Concordato. Perché diamine, Microsoft non ritiene che ciò possa accadere. Lo farò salire sul palo della bandiera. – sohtimsso1970

+0

Sì, era così. Il codice hash è un complemento a due. Grande. Bene, prova/lo capisco, immagino. – sohtimsso1970

+0

"Perché diamine Microsoft non ritiene che ciò potrebbe accadere." Forse perché hanno calcolato che le probabilità erano circa 1 su 2^32? Anche se è certamente concepibile che qualcosa sulla loro implementazione della funzione hash rende le probabilità molto più alte. – MatrixFrog

Problemi correlati