使用MemoryCache而不是ConccurentDictionary的常见模式是什么?

时间:2015-12-25 13:16:53

标签: c# dictionary memorycache

我的代码通过等待已经运行的操作的结果来处理并发请求。对数据的请求可能同时使用相同/不同的凭证(包括空凭证)。

对于每个唯一的凭证集合,最多可以有一个GetDataInternal调用正在进行中,其中一个调用的结果在准备就绪时返回给所有排队的服务员

private static readonly Credentials EmptyCredentials = 
new Credentials
{
    SqlCredentials = null,
    ExchangeCredentials = null
}; // added it to avoid ArgumentNullException inside GetOrAdd if Credentials == null

private readonly ConcurrentDictionary<Credentials, Lazy<Data>> Cache = 
             new ConcurrentDictionary<Credentials, Lazy<Data>>();

public Data GetData(Credentials credential)
{
    Lazy<Data> data = new Lazy<Data>(() => GetDataInternal(credential));
    Lazy<Data> lazyData = Cache.GetOrAdd(credential ?? EmptyCredentials, data);

    bool isAdded = ReferenceEquals(data, lazyData); 

    try
    {
       return lazyData.Value;
    }
    finally
    {
       if (isAdded)
       {
            Cache.TryRemove(credential ?? EmptyCredentials, out lazyData);
        }
    }
}

我添加了finally块,因为我需要更新我的字典(保持最新)。只允许创建缓存值的线程将其删除,以防止比赛。

但我想停止使用ConccurentDictionaryfinally阻止而不是我想使用MemoryCacheMemoryCache有一个驱逐策略,因此它可以抛弃不再需要的条目或者你没有足够的内存。这正是我所需要的。

如何更改以下行

Lazy<Data> lazyData = Cache.GetOrAdd(credential ?? EmptyCredentials, data);

使用MemoryCache?

Lazy<Data> lazyData = (Lazy<Data>)MemoryCache.Default.AddOrGetExisting(..., data, 
                                                                    new CacheItemPolicy());

那么,我怎样才能获得我的关键值?

1 个答案:

答案 0 :(得分:0)

请看以下解决方案,但我不确定是否正确

public Data GetData(Credentials credential)
{
   var data = new Lazy<Data>(() => GetCurrentInternal(credential));
   var lazydata  = (Lazy<Data>)MemoryCache.Default.AddOrGetExisting(
                   (credential ?? EmptyMetadataCredentials).ToString(),
                    data,
                    DateTime.Now.AddMinutes(5));

    return (lazydata ?? data).Value;
}