2009-09-16 25 views
19

जब आप एक पूर्ण समाप्ति दिनांक के साथ System.Web.Caching.Cache पर कोई आइटम जोड़ते हैं, जैसा कि निम्न उदाहरण में है, Asp.Net कैसे व्यवहार करता है? यह होता है:Asp.Net कब समाप्त हो गया कैश आइटम निकालें?

  1. बस वह आइटम के रूप में समाप्त हो गई है, तो अमल अगले पहुँच प्रयास पर CacheItemRemovedCallback निशान?

  2. आइटम को कैश से हटाएं और तुरंत CacheItemRemovedCallback निष्पादित करें?

    HttpRuntime.Cache.Insert(key, 
             new object(), 
             null, 
             DateTime.Now.AddSeconds(seconds), 
             Cache.NoSlidingExpiration, 
             CacheItemPriority.NotRemovable, 
             OnCacheRemove); 
    

MSDN संकेत मिलता है कि यह तुरंत होता दिखाई देता है। उदाहरण के लिए, the "Expiration" section of the "ASP.NET Caching Overview" कहता है "जब वे समाप्त हो जाते हैं तो ASP.NET स्वचालित रूप से कैश से आइटम्स को हटा देता है।" इसी तरह, "How to: Notify an Application When an Item Is Removed from the Cache" विषय का उदाहरण कहता है "यदि GetReport [उदाहरण में एक विधि] पर कॉल के बीच 15 सेकंड से अधिक समय समाप्त हो जाता है, तो एएसपी.नेट रिपोर्ट को कैश से हटा देता है।"

फिर भी, इनमें से कोई भी स्पष्ट नहीं है। वे यह नहीं कहते कि "कॉलबैक तुरंत निष्पादित किया जाता है" और मैं कल्पना कर सकता हूं कि उनके लेखकों ने एक आइटम को 'हटाने' के रूप में ऊपर दिए गए विकल्प 1 को कैसे सोचा होगा। तो मैंने एक त्वरित और गंदे परीक्षण किया, और देखो, यह तुरंत निष्पादित प्रतीत होता है - मुझे नियमित रूप से साठ सेकंड की कॉलबैक मिलती है जब भी कोई मेरी साइट तक नहीं पहुंचता है।

फिर भी, मेरा परीक्षण त्वरित और गंदा था, और टिप्पणियों में Is there a way to run a process every day in a .Net web application without writing a windows service or SQL server jobs के जवाब में, किसी ने सुझाव दिया है कि Asp.Net वास्तव में कॉलबैक को हटाने और निष्पादन को रोक देता है जब तक कि कुछ कैश तक फिर से पहुंचने का प्रयास नहीं करता।

क्या कोई इसे आधिकारिक रूप से व्यवस्थित कर सकता है या क्या इसे केवल कार्यान्वयन विस्तार माना जाता है?

+2

मुझे नहीं लगता कि उस प्रश्न का आधिकारिक उत्तर हो सकता है क्योंकि, जैसा कि रेमंड चेन अक्सर इंगित करना पसंद करते हैं, आप सॉफ़्टवेयर के एक संस्करण के व्यवहार को भविष्य के सभी संस्करणों के लिए आधिकारिक मानते हैं। मेरे अनुभव में यह एक बुरा विचार है क्योंकि एएसपी.नेट किसी भी समय अपना व्यवहार बदल सकता है और अपना आवेदन तोड़ सकता है। – dkackman

+1

आप इसका परीक्षण क्यों नहीं करते हैं। अपनी कॉलबैक पर एक फ़ाइल को लिखें और निर्माण की तारीख देखें और यह समाप्ति से कैसे संबंधित है। –

+0

@ डक्कमैन - मुझे "अब और हमेशा के लिए" उत्तर की आवश्यकता नहीं है, मैं .NET 2.0 और 3.5 के लिए आधिकारिक उत्तरों के लिए बसने के लिए तैयार हूं। यह मेरे लिए केवल एक कार्यान्वयन विवरण की तरह प्रतीत नहीं होता है: मैं प्रलेखन से कहीं कहने की अपेक्षा करता हूं कि वास्तविक निष्कासन निश्चित नहीं है यदि वह मामला था। शायद एमएस असहमत है। मैं बस यह देखने की कोशिश कर रहा हूं कि मैंने दस्तावेज़ में कुछ अनदेखा किया है या नहीं। –

उत्तर

35

Reflector के लिए Hurray!

1) कुछ कैश आइटम तक पहुंचने की कोशिश करता है:

समय सीमा समाप्त कैश आइटम वास्तव में हटाया (और कॉलबैक कहा जाता है) है जब या तो कर रहे हैं।

2) ExpiresBucket.FlushExpiredItems विधि चलता है और आइटम पर जाता है। इस विधि को हर 20 सेकंड निष्पादित करने के लिए हार्ड-कोड किया गया है (स्टैक ओवरव्लो प्रश्न Changing frequency of ASP.NET cache item expiration पर स्वीकृत उत्तर प्रतिबिंबक के माध्यम से इस कोड के मेरे पढ़ने की पुष्टि करता है)। हालांकि, इसके लिए अतिरिक्त योग्यता की आवश्यकता है (जिसके लिए पढ़ा जाता है)।


Asp.Net सर्वर पर प्रत्येक सीपीयू के लिए एक कैश रखता है (मुझे यकीन है कि अगर यह इन तार्किक या शारीरिक सीपीयू का प्रतिनिधित्व नहीं कर रहा हूँ); इनमें से प्रत्येक CacheExpires उदाहरण रखता है जिसमें Timer है जो प्रत्येक बीस सेकंड में FlushExpiredItems विधि को कॉल करता है।

कैश समाप्ति डेटा की 'बकेट' का एक और संग्रह (ExpiresBucket उदाहरणों की एक सरणी) क्रमानुसार से अधिक यह विधि दोहराता, प्रत्येक बकेट के बदले में FlushExpiredItems विधि बुला।

इस विधि (ExpiresBucket.FlushExpiredItems) पहले दोहराता बाल्टी में सभी कैश वस्तुओं और अगर एक आइटम समाप्त हो गई है, के निशान यह समाप्त हो। फिर (मैं यहां पूरी तरह से सरलीकृत कर रहा हूं) यह CacheItemRemovedCallback निष्पादित करने वाले आइटम को पुन: सक्रिय करता है और उन्हें हटा देता है (वास्तव में, यह CacheSingle.Remove पर कॉल करता है, जो CacheInternal.DoRemove पर कॉल करता है, फिर CacheSingle.UpdateCache, फिर CacheEntry.Close, जो वास्तव में कॉलबैक को कॉल करता है)।

यह सब क्रमशः होता है, इसलिए एक मौका है कि कुछ पूरी प्रक्रिया को अवरुद्ध कर सकता है और चीजों को पकड़ सकता है (और कैश आइटम की समाप्ति को अपने निर्दिष्ट समाप्ति समय से वापस दबाएं)।

हालांकि, इस अस्थायी संकल्प पर, बीस सेकेंड के न्यूनतम समाप्ति अंतराल के साथ, प्रक्रिया का एकमात्र हिस्सा जो महत्वपूर्ण समय के लिए अवरुद्ध हो सकता है CacheItemRemovedCallbacks का निष्पादन है। इनमें से कोई भी अनुमानित रूप से दिए गए Timer के FlushExpiredItems थ्रेड को अनिश्चित काल तक अवरुद्ध कर सकता है। (हालांकि बीस सेकंड बाद में, Timer एक और FlushExpiredItems धागा अंडे होगा।)

संक्षेप में, Asp.Net नहीं गारंटी है कि यह निर्दिष्ट समय पर कॉलबैक निष्पादित करेंगे करता है, लेकिन यह कुछ शर्तों के तहत ऐसा ही करेगा। जब तक समाप्ति अंतराल बीस सेकेंड से अधिक अलग हो, और जब तक कैश को समय लेने वाली CacheItemRemovedCallbacks (वैश्विक रूप से - किसी भी कॉलबैक संभावित रूप से किसी अन्य के साथ हस्तक्षेप कर सकता है) निष्पादित करने की आवश्यकता नहीं है, तो यह शेड्यूल पर समाप्ति कॉलबैक निष्पादित कर सकता है। यह कुछ अनुप्रयोगों के लिए पर्याप्त होगा, लेकिन दूसरों के लिए कम हो जाएगा।

+3

उत्कृष्ट, इसमें खोदने के लिए धन्यवाद। मुझे यकीन है कि यह कई वर्षों पहले रिफ्लेक्टर में इसके माध्यम से खोदने के बाद से सुधार हुआ है। इसके अलावा, एएसपी.नेट 4 में कैशिंग के लिए अतिरिक्त संवर्धन शामिल हैं, जिनमें से कुछ यहां सूचीबद्ध हैं: http://www.asp.net/learn/whitepapers/aspnet40/ –

+1

मेरी खुशी - यह बहुत दिलचस्प साबित हुई। बेशक, अब जब आप इसे लाए हैं, तो मुझे अपने सप्ताहांत का हिस्सा नवीनतम 4.0 बीटा असेंबली को देखने के लिए खर्च करना होगा, आपको विस्फोट! ;) –

5

कालबाह्य आइटम तुरंत कैश से नहीं हटाए जाते हैं, उन्हें बस समाप्त होने के रूप में चिह्नित किया जाता है। कैश मिस होने तक आपको कॉलबैक नहीं मिलता है। मैं एएसपी.NET 1.1 दिनों, and it hasn't changed में इस पीठ में भाग गया।

ऐसे मामले हो सकते हैं जहां समय सीमा समाप्त हो जाती है - जैसे कि कम स्मृति और उच्च CPU है - लेकिन आप उस पर भरोसा नहीं कर सकते हैं।

मैं आमतौर पर एक टाइमर का उपयोग करता हूं जो नियमित रूप से कैश को पुनः लोड करता है।

+1

मुझे आपके लेख में कैश की समाप्ति के लिए चुनी गई तकनीक पसंद है! लेकिन मैं अभी भी संदिग्ध हूं: मेरी टेस्ट साइट पूरे दिन चल रही है, मेरी मशीन पर चलने वाले वस्तुतः कुछ भी नहीं है, हर मिनट अपने कॉलबैक को कर्तव्यपूर्वक मार रहा है। आप क्यों कहते हैं कि वे केवल समाप्त होने के रूप में चिह्नित हैं? क्या यह स्टीव स्मिथ लेख से जुड़ा हुआ है? (http://msdn.microsoft.com/en-us/library/aa478965.aspx) वह केवल * asserts * कि समाप्त हो चुके कैश किए गए आइटम हटाए नहीं जाते हैं - और ... –

+0

... यह थोड़ा अस्पष्ट है कि वह बात कर रहा है या नहीं विशेष कैश की समाप्ति या केवल वह जिसका उपयोग करता है (NoAbsoluteExpiration/TimeSpan.Zero कॉन्फ़िगरेशन) के बारे में। कृपया मुझे यह भी जोड़ने दें कि मेरा मतलब स्टीव (या आप!) के प्रति अपमानजनक नहीं है, जिसने बड़े पैमाने पर .NET समुदाय में योगदान दिया है। यह मेरी आंखों के साथ जो दिखता है उसके विपरीत है (और मुझे यकीन है कि मेरे परीक्षण उच्च स्मृति/सीपीयू उपयोग से खराब नहीं होते हैं)। मुझे लगता है कि मुझे प्रतिबिंब डाउनलोड करने और खुद के लिए देखने की ज़रूरत है, और किस बिंदु पर मैं खुशी से इसे अपडेट करूँगा और कुछ अच्छी तरह से योग्य कौवा खाऊंगा। :) –

+0

मुझे गलत सिद्ध होना अच्छा लगेगा! मैंने कॉलबैक को .NET 1.1, 2.0, या 3.5 में भरोसेमंद नहीं देखा है। क्या आपके पास ऐसी साइट है जो साइट को जीवंत रखने वाली साइट को पिंग कर रही है?क्या आप अपने कोड और होस्टिंग पर अधिक विशिष्ट जानकारी दे सकते हैं? –

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