Không cần phải khóa toàn bộ phiên bản bộ đệm, thay vào đó chúng tôi chỉ cần khóa khóa cụ thể mà bạn đang chèn. Tức là không cần phải chặn lối vào nhà vệ sinh nữ khi bạn sử dụng nhà vệ sinh nam :)
Việc triển khai bên dưới cho phép khóa các khóa bộ nhớ cache cụ thể bằng cách sử dụng một từ điển đồng thời. Bằng cách này, bạn có thể chạy GetOrAdd () cho hai khóa khác nhau cùng một lúc - nhưng không cho cùng một khóa cùng một lúc.
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;
}
}