diff --git a/src/Orchard/Caching/Cache.cs b/src/Orchard/Caching/Cache.cs index 4f0bb402a..20e43cf1e 100644 --- a/src/Orchard/Caching/Cache.cs +++ b/src/Orchard/Caching/Cache.cs @@ -1,31 +1,35 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; namespace Orchard.Caching { public class Cache : ICache { - private readonly Dictionary _entries; + private readonly ConcurrentDictionary _entries; public Cache() { - _entries = new Dictionary(); + _entries = new ConcurrentDictionary(); } public TResult Get(TKey key, Func, TResult> acquire) { - CacheEntry entry; - if (!_entries.TryGetValue(key, out entry) || entry.Tokens.Any(t => !t.IsCurrent)) { - entry = new CacheEntry { Tokens = new List() }; - - var context = new AcquireContext(key, volatileItem => entry.Tokens.Add(volatileItem)); - entry.Result = acquire(context); - _entries[key] = entry; - } + var entry = _entries.AddOrUpdate(key, + // "Add" lambda + k => CreateEntry(k, acquire), + // "Update" lamdba + (k, currentEntry) => (currentEntry.Tokens.All(t => t.IsCurrent) ? currentEntry : CreateEntry(k, acquire))); return entry.Result; } + private static CacheEntry CreateEntry(TKey k, Func, TResult> acquire) { + var entry = new CacheEntry { Tokens = new List() }; + var context = new AcquireContext(k, volatileItem => entry.Tokens.Add(volatileItem)); + entry.Result = acquire(context); + return entry; + } + private class CacheEntry { public TResult Result { get; set; } public IList Tokens { get; set; } } } - }