2013-05-13 4 views
14

मैं अपने कुछ ऑब्जेक्ट्स को कैश करने के लिए System.Runtime.Caching.MemoryCache का उपयोग करना चाहता हूं। मैं यह सुनिश्चित करना चाहता हूं कि ऑब्जेक्ट दिन में एक बार ताज़ा हो (पूर्ण समाप्ति) लेकिन मैं इसे समाप्त करना चाहता हूं अगर इसे अंतिम घंटे (स्लाइडिंग समाप्ति) में उपयोग नहीं किया गया है। मैं करने की कोशिश:स्लाइडिंग और पूर्ण समाप्ति को जोड़ना

object item = "someitem"; 
var cache = MemoryCache.Default; 
var policy = new CacheItemPolicy(); 
policy.AbsoluteExpiration = DateTime.Now.AddDays(1); 
policy.SlidingExpiration = TimeSpan.FromHours(1); 
cache.Add("somekey", item, policy); 

लेकिन मैं के साथ एक "ArgumentException" हो रही है "AbsoluteExpiration DateTimeOffset.MaxValue या SlidingExpiration होना चाहिए TimeSpan.Zero होना चाहिए।"

उत्तर

9

आप CacheEntryChangeMonitor का उपयोग करके दोनों योजनाओं कैश समाप्ति लागू कर सकते हैं को लागू करें। पूर्ण समाप्ति के साथ जानकारी के बिना कैश आइटम डालें, फिर एक खाली मॉनिटर बनाएं इस आइटम के साथ बदलें और इसे दूसरे कैश आइटम से लिंक करें, जहां आप वास्तव में एक स्लाइडिंग टाइम आउट जानकारी सहेज लेंगे।

 object data = new object(); 
     string key = "UniqueIDOfDataObject"; 
     //Insert empty cache item with absolute timeout 
     string[] absKey = { "Absolute" + key }; 
     MemoryCache.Default.Add("Absolute" + key, new object(), DateTimeOffset.Now.AddMinutes(10)); 

     //Create a CacheEntryChangeMonitor link to absolute timeout cache item 
     CacheEntryChangeMonitor monitor = MemoryCache.Default.CreateCacheEntryChangeMonitor(absKey); 

     //Insert data cache item with sliding timeout using changeMonitors 
     CacheItemPolicy itemPolicy = new CacheItemPolicy(); 
     itemPolicy.ChangeMonitors.Add(monitor); 
     itemPolicy.SlidingExpiration = new TimeSpan(0, 60, 0); 
     MemoryCache.Default.Add(key, data, itemPolicy, null); 
+0

मुझे लगता है कि यह काम करता है तो यह एक अच्छा कामकाज है। धन्यवाद – Andres

-2

DateTime.Now.AddDays(1) डेटटाइम ऑफसेट वापस नहीं करता है, लेकिन डेटटाइम (AddDays())।

तो यह संभवतः एक अवैध तर्क है।

तो इसके बजाय, DateTimeOffset.Now.AddDays(1) (DateTimeOffset) आज़माएं। जब MemoryCache.Add

if (policy.AbsoluteExpiration != ObjectCache.InfiniteAbsoluteExpiration && policy.SlidingExpiration != ObjectCache.NoSlidingExpiration) 
    { 
     throw new ArgumentException(R.Invalid_expiration_combination, "policy"); 
    } 

तो, निरपेक्ष के इस संयोजन बुला और समय सीमा समाप्ति स्लाइडिंग देशी रूप समर्थित नहीं है

+3

-1: एक [अंतर्निहित ऑपरेटर] है (http://msdn.microsoft.com/en-us/library /system.datetimeoffset.op_implicit.aspx) 'डेटटाइम' से 'डेटटाइम ऑफसेट' तक। –

+0

इसके बारे में नहीं पता था। अद्यतन के लिए धन्यवाद। – ThaMe90

3

ILSpy साथ एक त्वरित प्रतिबिंब इस कोड को प्रदर्शित करते हैं।

आपको अपने आप को एक कस्टम कार्यान्वयन में बदलना चाहिए।

2

आपके पास दो विकल्प:

MemoryCache से
  1. इनहेरिट या उसे अपने जनक ObjectCache है और अपने खुद के कैशिंग तंत्र को लागू करने।
  2. एक ChangeMonitor जो हो सकता है more difficult (see Note to Inheritors)
2

dieguitofernandez जवाब देने के लिए एक छोटी सी अतिरिक्त नोट्स (जो, btw है एक बहुत अच्छा समाधान):

ChangeMonitor सही समय AbsoluteExpiration तक पहुँच जाता है पर fiering नहीं है, क्योंकि समय सीमा समाप्ति नहीं है हर सेकेंड की जांच की। दूसरे कैश किए गए आइटम को अधिसूचित होने तक इसमें कई सेकंड लग सकते हैं। निरपेक्ष निष्पादन के रूप में 1 दिन के साथ इससे कोई फर्क नहीं पड़ता, लेकिन यदि आपको दोनों समाप्ति की सटीक होने की आवश्यकता है (जैसे मैंने किया) तो आपको पहले दोनों कुंजी और पूर्ण-कुंजी का उपयोग करना होगा।

if (cache.Contains("Absolute" + key) && cache.Contains(key)) 

इस तरह दोनों समाप्ति तुरंत जांच की जाती है और आप सुनिश्चित कर सकते हैं कि आइटम की समयसीमा समाप्त नहीं हुई है।

(मैं इस टिप्पणी के रूप में क्योंकि मैं यहाँ नया हूँ खेद पोस्ट कर सकता,!)

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