Es ist nicht erforderlich, die gesamte Cache-Instanz zu sperren, sondern nur den spezifischen Schlüssel zu sperren, für den Sie einfügen. Dh keine Notwendigkeit, den Zugang zur weiblichen Toilette zu blockieren, während Sie die männliche Toilette benutzen :)
Die folgende Implementierung ermöglicht das Sperren bestimmter Cache-Schlüssel unter Verwendung eines gleichzeitigen Wörterbuchs. Auf diese Weise können Sie GetOrAdd () für zwei verschiedene Schlüssel gleichzeitig ausführen - jedoch nicht für denselben Schlüssel zur gleichen Zeit.
using System;
using System.Collections.Concurrent;
using System.Web.Caching;
public static class CacheExtensions
{
private static ConcurrentDictionary<string, object> keyLocks = new ConcurrentDictionary<string, object>();
public static T GetOrAdd<T>(this Cache cache, string key, int durationInSeconds, Func<T> factory)
where T : class
{
var value = cache.Get(key);
if (value == null)
{
lock (keyLocks.GetOrAdd(key, new object()))
{
value = cache.Get(key);
if (value == null && (value = factory()) != null)
{
cache.Insert(
key: key,
value: value,
dependencies: null,
absoluteExpiration: DateTime.Now.AddSeconds(durationInSeconds),
slidingExpiration: Cache.NoSlidingExpiration,
priority: CacheItemPriority.Default,
onRemoveCallback: null);
}
keyLocks.TryRemove(key, out object locker);
}
}
return value as T;
}
}