簡體   English   中英

如何在c#中實現通用緩存管理器

[英]How to implement a generic cache manager in c#

我正在嘗試實現通用緩存管理器,但是我不確定如何進行鎖定。

到目前為止我有以下內容,但是如果我有兩個具有相同返回類型的緩存條目,那么我猜測將使用相同的鎖對象!

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()並將用於鎖定。

除非真的需要,否則你永遠不應該鎖定你的緩存代碼。 如果您不想使用任何眾所周知的緩存,請使用Concurrent字典。

我還說你可能應該使用System.Runtime.MemorCache

或者您使用的解決方案可以為您抽象,例如我的CacheManager https://github.com/MichaCo/CacheManager ;)

我不確定你應該使用鎖,alos,為什么不使用MemoryCache而不是ICache接口? 內存緩存不夠通用嗎? 為什么強制緩存時間是分鍾,你應該將時間跨度傳遞給緩存方法,我會更通用。

幾個月前我實現了一個緩存管理器版本 ,但它是面向Web的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM