2010-10-03 9 views
8
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using System.Runtime.Caching; 

using Xunit; 

namespace Demo.Caching.Test 
{ 
    class MemoryCacheManagerTest 
    { 
     [Fact] 
     public void Test() 
     { 
      CacheItemPolicy policy = new CacheItemPolicy(); 
      policy.SlidingExpiration = TimeSpan.FromSeconds(1); 

      MemoryCache.Default.Set("cacheKey4", 4, policy); 
      Assert.Equal(4, MemoryCache.Default.Get("cacheKey4")); 
      System.Threading.Thread.Sleep(600); 
      Assert.Equal(4, MemoryCache.Default.Get("cacheKey4")); 
      System.Threading.Thread.Sleep(600); 
      Assert.Equal(4, MemoryCache.Default.Get("cacheKey4")); 
      // Here I get error 
      // Expected: 4, Actual: (null) 

      System.Threading.Thread.Sleep(1000); 
      Assert.Null(MemoryCache.Default.Get("cacheKey4")); 
     } 
    } 
} 
+0

सभी कोड, अच्छा सवाल के बारे में! – stephen

उत्तर

4

शायद कारण यह है कि नींद गैर-निर्धारक है। यह आपके धागे को 600 मिलीसेकंड के लिए रोक नहीं देता है। यह के लिए धागे को कम से कम 600 एमएस के लिए रोक देता है। यह आपके द्वारा महसूस किए बिना 1 सेकंड स्लाइडिंग समाप्ति पर बहुत अच्छी तरह से जा सकता है।

+0

@StripplingWarrior से 'PollingInterval' के बारे में भी जवाब देखें। चाल यह प्रतीत होती है कि मतदान अंतराल के नीचे देरी का अपर्याप्त रूप से इलाज किया जाता है। –

0

मुझे एक ही समस्या थी। लेकिन वास्तव में समस्या क्या है @ कोलिन ने कहा। Thread.Sleep एक सेकंड से अधिक समय ले रहा है।

तो मैं एक बड़ा देरी

[TestMethod] 
public void Sliding() 
{ 
    MemoryCache.Default.Add("test", 1, 
     new CacheItemPolicy 
     { 
      SlidingExpiration = new TimeSpan(0, 0, seconds: 5) 
     }); 

    for (int i = 0; i < 15; ++i) 
    { 
     Assert.IsNotNull(MemoryCache.Default.Get("test")); 
     Thread.Sleep(700); 
    } 
} 

के साथ एक परीक्षण किए गए और यह पारित कर दिया। मुझे यकीन नहीं है कि यह हमेशा काम करेगा - शायद नहीं - लेकिन मैंने अभी पुष्टि की है कि स्लाइडिंग वास्तव में काम करती है।

4

यह नहीं है, जैसा कि अन्य उत्तरों ने थ्रेड के कारण कहा है। नींद() अपेक्षा से अधिक समय ले रहा है।

MemoryCache अपने स्लाइडिंग टाइमर के साथ बहुत ही कमजोर प्रतीत होता है। मुझे लगता है कि ऐसा इसलिए है कि वे लॉकिंग से बच सकते हैं, और कैश के प्रदर्शन को बनाए रख सकते हैं।

  • यदि आप 1 सेकंड या उससे कम की स्लाइडिंग समाप्ति सेट करते हैं, तो कैश आइटम को दूसरी बार बेदखल कर दिया जाएगा चाहे कितनी बार उन्हें एक्सेस किया जा सके।
  • 1 और 2 सेकंड के बीच, अभी भी कैश आइटमों को बेदखल करने का मौका प्रतीत होता है। यह कुछ हद तक उस भार पर निर्भर हो सकता है जो कंप्यूटर के अधीन है, और यह निश्चित रूप से इस बात पर निर्भर करता है कि वस्तुओं को कब एक्सेस किया जाता है, लेकिन जैसा कि आप सोचते हैं उतना अनुमानित नहीं है। उदाहरण के लिए:
    • यदि मैं 1.001 सेकंड से 1.24 सेकेंड तक कहीं भी समाप्ति सेट करता हूं, और 200 या 250 मिलीसेकंड तक पहुंच के बीच सोता है, तो यह कैश में मान रखता है; लेकिन अगर मैं 201 या 24 9 मिलीसेकंड के लिए सोता हूं, तो आइटम बेदखल हो जाता है।
    • यदि मैं 1.25 सेकंड की समाप्ति निर्धारित करता हूं, तो मैं बिना किसी समस्या के 624 मिलीसेकंड तक सो सकता हूं, लेकिन अगर मैं 625 मिलीसेकंड हिट करता हूं तो कैश आइटम बेदखल हो जाता है।
  • एक बार जब आप 2-सेकंड की समाप्ति पर आते हैं, तो यह ठीक से काम करता प्रतीत होता है भले ही आप केवल समाप्ति की समय सीमा से पहले ही आइटम तक पहुंच सकें।

तो मुझे लगता है कि पाठ 2 सेकंड के तहत मूल्यों के लिए सही ढंग से काम करने के लिए स्लाइडिंग समाप्ति पर भरोसा नहीं करना है। इसमें PollingInterval के साथ 2 सेकंड पर सेट होने के साथ कुछ करना पड़ सकता है।

कोड:

var span = TimeSpan.FromSeconds(1); // change as necessary 
var sw = new Stopwatch(); 
var cache = new MemoryCache("testcache"); 
sw.Start(); 
cache.Add("test", "hello", new CacheItemPolicy{SlidingExpiration = span}); 
Console.WriteLine(sw.ElapsedMilliseconds); 
for (int i = 0; i < 40; i++) 
{ 
    Console.WriteLine(sw.ElapsedMilliseconds + ": " + cache.Get("test")); 
    Thread.Sleep(50); // change as necessary 
} 
संबंधित मुद्दे