c# - 如何在 C# 中实现通用缓存管理器

标签 c# generics locking

我正在尝试实现通用缓存管理器,但我不确定如何进行锁定。

到目前为止我有以下内容,但是如果我有两个具有相同返回类型的缓存条目,那么我猜会使用相同的锁对象!

public class CacheManager : ICacheManager
{
    static class TypeLock<T>
    {
        public static readonly object SyncLock = new object();
    }
    private readonly ICache _cache;
    public CacheManager(ICache cache)
    {
        if (cache == null)
            throw new ArgumentNullException("cache");

        _cache = cache;
    }

    public TResult AddCache<TResult>(string cacheKey, Func<TResult> acquire, int cacheDurationInMinutes) where TResult : class
    {
        return AddCache(cacheKey, null, acquire, cacheDurationInMinutes);
    }

    public TResult AddCache<TResult>(string cacheKey, CacheDependency dependency, Func<TResult> acquire, int cacheDurationInMinutes) where TResult : class
    {
        var entry = acquire.Invoke();
        if (entry != null)
        {
            if (dependency != null)
                _cache.InsertWithDependency(cacheKey, entry, dependency, DateTime.Now.AddMinutes(cacheDurationInMinutes));
            else
                _cache.Insert(cacheKey, entry, DateTime.Now.AddMinutes(cacheDurationInMinutes));
        }
        return entry;
    }

    public TResult GetOrAddCache<TResult>(string cacheKey, Func<TResult> acquire, int cacheDurationInMinutes) where TResult : class
    {
        return GetOrAddCache(cacheKey, null, acquire, cacheDurationInMinutes);
    }

    public TResult GetOrAddCache<TResult>(string cacheKey, CacheDependency dependency, Func<TResult> acquire, int cacheDurationInMinutes) where TResult : class
    {
        var entry = _cache.GetItem(cacheKey) as TResult;

        if (entry == null)
        {
            lock (TypeLock<TResult>.SyncLock)
            {
                entry = _cache.GetItem(cacheKey) as TResult;
                if (entry == null)
                {
                    entry = acquire.Invoke();
                    if (entry != null)
                    {
                        if (dependency != null)
                            _cache.InsertWithDependency(cacheKey, entry, dependency,
                                                        DateTime.Now.AddMinutes(cacheDurationInMinutes));
                        else
                            _cache.Insert(cacheKey, entry, DateTime.Now.AddMinutes(cacheDurationInMinutes));
                    }
                }
            }
        }

        return entry;
    }
}

如有任何帮助,我们将不胜感激!

最佳答案

你是对的,这将对所有相同类型的缓存条目使用相同的锁。为了使您的实际缓存方法(内存、文件、数据库...)独立于此缓存管理器,我建议为每个缓存条目存储一个额外的同步对象,这样您的缓存条目将看起来像 Tuple<object, TResult>。而不仅仅是 TResult , 其中object将是 new object()对于每个条目,将用于锁定。

关于c# - 如何在 C# 中实现通用缓存管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13520364/

相关文章:

c# - 等待释放文件锁的正确模式是什么?

c# - 未知 url 的 MVC 3 路由

java - 为通用数组包装原语时出现未经检查的强制转换警告

Java 泛型上限通配符限制

java - 为什么 ConcurrentHashMap 中的 get 方法是阻塞的?

.net-2.0 - 如何确保获取和设置操作的原子性以重定向 Console.Out 以记录控制台输出?

C# 和 SerialPort 类截断数据

c# - 通过 sql 表中的 100,000 条记录进行通配符搜索的最佳优化技术是什么

C# CopyFromScreen 问题

java - 无法在 Java 中使用 List 类进行向下转换