2010-09-01 11 views
18

यह मैंने कभी देखा है कि सबसे अजीब त्रुटियों में से एक है।कैश कुंजी त्रुटि का कारण बनता है "दो जुड़वां पूरक संख्या के न्यूनतम मान को नकारात्मक करना अवैध है।"

मैं HttpRuntime कैश से मूल्यों को वापस करने के लिए एक बहुत ही सरल कॉल कर रहा हूं। कॉल है:

return HttpContext.Current.Cache[cacheKey]; 

यदि यह शून्य हो जाता है, तो यह ठीक है। मैं जांचता हूं कि लौटाया गया मूल्य शून्य है और तदनुसार कार्य करें। मैं इस कॉल का उपयोग लंबे समय से कर रहा हूं।

हाल ही में, किसी कारण, जब cacheKey इस सटीक मान पर सेट है के लिए:

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

एक System.OverflowException फेंक दिया जाता है: एक दुक्की पूरक संख्या के न्यूनतम मूल्य को नकारने अमान्य है।

कॉल, संबंधित कोड या सर्वर के बारे में कुछ भी नहीं बदला है। यदि कैशकी के पास थोड़ा अलग वर्ण हैं, तो यह पूरी तरह से ठीक काम करता है।

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

सूचना, उन दो तार के बीच फर्क सिर्फ इतना समय वर्ण है: उदाहरण के लिए, इस cacheKey किसी भी अपवाद फेंकने के बिना अशक्त रिटर्न 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]) को बदलने की कोशिश की है, लेकिन है कि कोई फर्क पड़ा। मुझे पता है कि यह वही अंतर्निहित कैश प्रदाता है, लेकिन मैंने सोचा कि शायद अलग कॉल एक फर्क पड़ता है। कोई पाँसा नहीं।

+3

मुझे लगता है कि यह पहली "अजीब त्रुटि" प्रश्न है जिसे मैंने देखा है कि वास्तव में एक अजीब त्रुटि थी। :) – Guffa

उत्तर

17

यह आपके प्लेटफ़ॉर्म, GetHashCode() (System.String में) जैसा दिखता है कि सटीक स्ट्रिंग -2147483648 लौट रही है। आप उस स्ट्रिंग को डालकर और इसके लिए GetHashCode() को बस कॉल करके (जैसा मैंने किया) परीक्षण कर सकते हैं। प्रत्येक स्ट्रिंग को हैश कोड मिलता है, और यह एक है। तो क्या? अच्छी तरह से ....

CacheMultiple.UpdateCache अपने प्रमुख स्ट्रिंग पर GetHashCode() कहता है, तो GetCacheSingle() कहता है, जो Math.Abs कहता है, जो अंत में कहता है AbsHelper। AbsHelper अपवाद फेंकता है यदि संख्या बिल्कुल -2147483648 के बराबर है! (चूंकि absoulte मान अधिकतम मूल्य से अधिक होगा)

तो, बधाई हो, आपने GetHashCode लॉटरी जीती - 2^32 संभावित मानों में से, आपको सही (अच्छा, गलत) मिला । दुर्भाग्यवश, ऐसा लगता है कि Web.Cache के आंतरिक इसे बिल्कुल संभाल नहीं पाते हैं, इसलिए आपको अपनी स्ट्रिंग पर GetHashCode पर कॉल करना होगा ताकि यह देखने के लिए कि यह -2147483648 के बराबर था, और यदि स्ट्रिंग थोड़ा बदलता है। या, इस अपवाद के लिए जाल - और यदि पकड़ा गया है, तो अपनी कुंजी को थोड़ा बदलने के बाद पुनः प्रयास करें (एक अनुमानित तरीके से ताकि आप इसे उसी तरह फिर से बना सकें)।

अच्छा बग ढूंढें - मैं शायद आगे बढ़ूंगा और कनेक्ट साइट पर एक बग डालूंगा यदि मैं आप थे ... मेरी राय में, कॉलर की ज़िम्मेदारी नहीं होना चाहिए ताकि एज केस की समस्याओं का पता लगाना और सही हो आंतरिक कार्यान्वयन निर्णयों के कारण।

+0

दिलचस्प। यह समझ आता है। _ "मेरी राय में, आंतरिक कार्यान्वयन निर्णयों के कारण किनारे के मामले की समस्याओं का पता लगाने और सही करने के लिए कॉलर की ज़िम्मेदारी नहीं होनी चाहिए।" _ सहमत। क्यों माइक्रोसॉफ्ट माइक्रोसॉफ्ट पर विचार नहीं करेगा कि ऐसा हो सकता है। मैं इसे अपने ध्वज ध्रुव को चलाऊंगा। – sohtimsso1970

+0

हाँ, वह था। हैश कोड एक जुड़वां पूरक है। महान। खैर, मुझे लगता है कि यह कोशिश/पकड़ है। – sohtimsso1970

+0

"क्यों माइक्रोसॉफ्ट माइक्रोसॉफ्ट पर विचार नहीं करेगा कि ऐसा हो सकता है।" हो सकता है क्योंकि उन्हें लगता है कि बाधाएं 2^32 में लगभग 1 थीं? हालांकि यह निश्चित रूप से कल्पना की जा सकती है कि उनके हैश फ़ंक्शन के कार्यान्वयन के बारे में कुछ वास्तव में बाधाओं को बहुत अधिक बनाता है। – MatrixFrog

संबंधित मुद्दे