Sto scrivendo una libreria di classi portatile che si rivolge a .NET 4.5, app di Windows Store e Windows Phone 8. Ho bisogno di un efficiente meccanismo di cache in memoria, quindi stavo pensando di usare ConcurrentDictionary<K,V>
, ma non è disponibile in WP8.Alternativa a ConcurrentDictionary per la libreria di classi portatili
Ci saranno molte letture e relativamente poche scritture, quindi idealmente mi piacerebbe una collezione che supporti letture prive di lock da più thread e che scriva da un singolo thread. Il non-Hashtable
non ha questa proprietà, according to MSDN, ma sfortunatamente non è disponibile nel PCL ...
Esiste un'altra classe di raccolta disponibile nel PCL che soddisfi questo requisito? In caso contrario, quale sarebbe un buon modo per ottenere la sicurezza della filettatura senza bloccare le letture? (Blocco in scrittura è OK, dato che non accadrà troppo spesso)
EDIT: grazie alla guida di JaredPar, alla fine ho implementato la cache in modo completamente senza blocchi, utilizzando ImmutableDictionary<TKey, TValue>
da Microsoft.Bcl.Immutable:
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();
}
}
Hai mai pensato di scrivere un tipo che avvolgesse un albero immutabile e facesse un CAS per le scritture? Questo ti darebbe le letture senza blocco, la scrittura CAS e potresti semplicemente usare l'albero AVL immutabile di Eric come struttura di supporto http://blogs.msdn.com/b/ericlippert/archive/2008/01/21/immutability-in- c-part-nine-academic-plus-my-avl-tree-implementation.aspx – JaredPar
@JaredPar, che cos'è "CAS"? –
CAS = confronta e scambia. – JaredPar