2013-08-21 20 views
9

.NET 4.5, Windows Mağaza uygulamaları ve Windows Phone 8'yi hedefleyen bir taşınabilir sınıf kitaplığı yazıyorum. Etkin bir bellek içi önbellek mekanizmasına ihtiyacım var, bu yüzden ConcurrentDictionary<K,V>'u kullanmayı düşünüyordum, ama WP8'de mevcut değil.Taşınabilir sınıf kitaplığı için ConcurrentDictionary için alternatif

Çok sayıda okunacak ve nispeten az sayıda yazı olacak, bu yüzden ideal olarak birden çok iş parçacığı için kilitlenmeyen okumaları destekleyen bir koleksiyonu ve tek bir iş parçacığıyla yazmak istiyorum. Jenerik olmayan Hashtable bu mülke sahiptir, according to MSDN, ancak maalesef PCL'de mevcut değildir ...

PCL'de bu gereksinimle eşleşen başka bir koleksiyon sınıfı var mı? Aksi halde, okuyucuyu okumadan kilitlemeden elde etmek için iyi bir yol ne olurdu? (Çok sık olmaz çünkü yazma işlemleri için kilitleme, Tamam)


DÜZENLEME: JaredPar rehberliğinde sayesinde, sonunda Microsoft.Bcl.Immutable den ImmutableDictionary<TKey, TValue> kullanarak, tamamen kilidi serbest biçimde Önbelleğimi uygulanan:

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

Değişmez bir ağaç içeren bir yazı yazmayı düşündünüz mü ve CAS yazıyor mu? Bu size kilitsiz okumalar verecek, CAS yazdı ve http://blogs.msdn.com/b/ericlippert/archive/2008/01/21/immutability-in- destek yapısı olarak Eric'in değişmez AVL ağacını kullanabiliyordunuz. c-bölüm-dokuz-akademik-artı-benim-avl-ağaç-application.aspx – JaredPar

+0

@JaredPar, "CAS" nedir? –

+0

CAS = Karşılaştırma ve takas. – JaredPar

cevap

4

Göz önünde bulundurulması gereken bir seçenek, değişmez bir arama ağacının üzerinde ince bir cephe yazmaktır. Web'de seçim yapabileceğiniz birkaç değişmez arama ağacı var. Genellikle özgür kilidi verecektir destek veri yapısı olarak kullanarak konuya

Eric Lipperts büyük yazının kapalı mayın dayandırmak. Ağaca yazılanlar CAS ile de kilitsiz bir şekilde yapılabilir. Bu, ConcurrentDictionary'dan biraz daha yavaş olacaktır çünkü aramalar O (1) 'e yaklaşmak yerine O (Log (N)) olur. Ama sizin için hile yapmalı

+0

Harika çözüm, teşekkürler! Kilitsiz yazmalarla ilgili olarak, bunu nasıl başaracağımı bilmiyorum ... eğer kilitlenmezse ve her bir yazı dizisi farklı bir kopyasını yaratırsa, ikincisi ilk yaptıklarının üzerine yazacaktır, değil mi? –

+0

Şu anda ağacı şu şekilde kullanıyorum: https://gist.github.com/thomaslevesque/92ad1f8643dfa7a2970a –

+0

@ThomasLevesque Yaptığım düzenlemelere bir bakın. Mantıklarını yorumlarda açıklamaya çalıştım https://gist.github.com/jaredpar/20fbdb7ad7fbbb4bd82d – JaredPar