2013-08-21 10 views
9

मैं एक पोर्टेबल क्लास लाइब्रेरी लिख रहा हूं जो .NET 4.5, विंडोज स्टोर ऐप और विंडोज फोन 8 को लक्षित करता है। मुझे एक कुशल इन-मेमोरी कैश तंत्र की आवश्यकता है, इसलिए मैं ConcurrentDictionary<K,V> का उपयोग करने के बारे में सोच रहा था, लेकिन यह WP8 में उपलब्ध नहीं है।पोर्टेबल क्लास लाइब्रेरी के लिए ConcurrentDictionary के लिए वैकल्पिक

कई पढ़े जाएंगे और अपेक्षाकृत कुछ लिखेंगे, इसलिए आदर्श रूप से मुझे एक संग्रह चाहिए जो एकाधिक धागे से लॉक-फ्री रीड का समर्थन करता है, और एक थ्रेड द्वारा लिखता है। गैर सामान्य Hashtable है कि संपत्ति, according to MSDN है, लेकिन दुर्भाग्य से यह पीसीएल में उपलब्ध नहीं है ...

वहाँ पीसीएल कि इस आवश्यकता से मेल खाता है में एक और संग्रह वर्ग उपलब्ध है? यदि नहीं, तो पढ़ने के लिए लॉक किए बिना थ्रेड सुरक्षा प्राप्त करने का एक अच्छा तरीका क्या होगा? (राईट के लिए ताला लगा ठीक है, क्योंकि यह भी अक्सर नहीं होगा)


संपादित करें: JaredPar के मार्गदर्शन के लिए धन्यवाद, मैं अंत में अपने कैश एक पूरी तरह से ताला मुक्त फैशन में Microsoft.Bcl.Immutable से लागू किया, ImmutableDictionary<TKey, TValue> का उपयोग कर:

class Cache<TKey, TValue> 
{ 
    private IImmutableDictionary<TKey, TValue> _cache = ImmutableDictionary.Create<TKey, TValue>(); 

    public TValue GetOrAdd(TKey key, [NotNull] Func<TKey, TValue> valueFactory) 
    { 
     valueFactory.CheckArgumentNull("valueFactory"); 

     TValue newValue = default(TValue); 
     bool newValueCreated = false; 
     while (true) 
     { 
      var oldCache = _cache; 
      TValue value; 
      if (oldCache.TryGetValue(key, out value)) 
       return value; 

      // Value not found; create it if necessary 
      if (!newValueCreated) 
      { 
       newValue = valueFactory(key); 
       newValueCreated = true; 
      } 

      // Add the new value to the cache 
      var newCache = oldCache.Add(key, newValue); 
      if (Interlocked.CompareExchange(ref _cache, newCache, oldCache) == oldCache) 
      { 
       // Cache successfully written 
       return newValue; 
      } 

      // Failed to write the new cache because another thread 
      // already changed it; try again. 
     } 
    } 

    public void Clear() 
    { 
     _cache = _cache.Clear(); 
    } 
} 
+0

क्या आपने एक ऐसा प्रकार लिखने पर विचार किया है जो एक अपरिवर्तनीय पेड़ को लपेटता है, और लिखने के लिए सीएएस करता है? इससे आपको लॉक फ्री रीड, सीएएस लिखना होगा और आप एरिक के अपरिवर्तनीय एवीएल पेड़ का समर्थन बैकिंग स्ट्रक्चर के रूप में कर सकते हैं http://blogs.msdn.com/b/ericlippert/archive/2008/01/21/immutability-in- सी-भाग-नौ-अकादमिक-प्लस-मेरा-एवीएल-पेड़-कार्यान्वयन.aspx – JaredPar

+0

@ जेरेडपायर, "सीएएस" क्या है? –

+0

सीएएस = तुलना और स्वैप करें। – JaredPar

उत्तर

4

विचार करने का एक विकल्प एक अपरिवर्तनीय खोज पेड़ पर पतला मुखौटा लिखना है। चुनने के लिए वेब पर कई अपरिवर्तनीय खोज पेड़ उपलब्ध हैं। मैं आमतौर पर विषय

पर एरिक Lipperts महान पोस्ट के बंद खदान का आधार समर्थन डेटा संरचना के रूप में इस का उपयोग करते हुए तुम मुक्त ताला दे देंगे। पेड़ को लिखना सीएएस के साथ लॉक फ्री फैशन में भी किया जा सकता है। यह ConcurrentDictionary से थोड़ा धीमा होगा क्योंकि ओ (1) के आने के बजाय लुकअप ओ (लॉग (एन)) हैं। लेकिन यह आपके लिए चाल है

+0

ग्रेट समाधान, धन्यवाद! लॉक-फ्री लिखने के बारे में, मुझे यकीन नहीं है कि इसे कैसे प्राप्त किया जाए ... अगर मैं लॉक नहीं करता हूं और प्रत्येक लेखक धागा एक अलग प्रति बनाता है, तो दूसरा व्यक्ति पहले क्या करेगा, इसे ओवरराइट करेगा, है ना? –

+0

यहां मैं अभी पेड़ का उपयोग कैसे कर रहा हूं: https://gist.github.com/thomaslevesque/92ad1f8643dfa7a2970a –

+0

@ थॉमस लेवेस्क ने मेरे द्वारा किए गए संपादन पर एक नज़र डालें। मैंने टिप्पणियों में तर्क को समझाने की कोशिश की https://gist.github.com/jaredpar/20fbdb7ad7fbbb4bd82d – JaredPar

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