在 IMemoryCache 中增加计数器

Increase counter inside IMemoryCache

我有以下情况:

//IMemoryCache is injected into class and into field _cache
public void IncreaseCounter(string key){

     int currectCount = _cache.Get<int>(key) + 1;
     _cache.Set<int>(key, currentCount);
}

但是我知道这不是最好的方法。我也想检查key是否存在,如果不存在,计数器应该是0然后增加到1.

我该怎么做?我知道方法 GetOrCreate(object, Func<>) 但我不知道如何实现它。

GetOrCreate 基本上是这样工作的:

   int currentCount = _cache.GetOrCreate(key, _ => 0); // pass key and 
                                                       // "new item factory"
   // now, if key exists, it will return the cached value
   // if it does not exist, it will 
   // - create a new entry,
   // - execute the passed-in factory function und set the returned value in cache,
   // - return the result of the passed-in factory
   _cache.Set(key, currentCount+1);

预期的工厂必须是一个 Func<ICacheEntry, TItem>,它转换为这种形式的委托:TItem FunctionName(ICacheEntry entry)。因此,一个函数采用 ICacheEntry 和 returns 类型的参数,无论您的值是什么类型。

_ => 0 与此匹配,因为它是一个 Func,它忽略了输入参数,只是 returns 0,这对于问题中的用例应该足够了。

看到 Example in Fiddle

using System;
using Microsoft.Extensions.Caching.Memory;
                    
public class Program
{
    public static void Main()
    {
        IMemoryCache cache = new MemoryCache(new MemoryCacheOptions());
        object key = new object();
        
        Console.WriteLine("{0}", cache.TryGetValue(key, out int val)?val:"key not found");
        
        Incr(key, cache);
        Console.WriteLine(cache.Get(key));
        
        Incr(key, cache);
        Console.WriteLine(cache.Get(key));
    }
    
    public static void Incr(object key, IMemoryCache cache)
    {
        int currentValue = cache.GetOrCreate(key, _ => 0);
        cache.Set(key, currentValue+1);
    }
}

生产

key not found
1
2

仅供参考 - 与所讨论的特定用例无关:

请注意,我在这里使用了“忽略”(_ => )。如果需要,您实际上可以使用工厂内新创建的缓存条目中的信息(或在其上设置值):

int currentValue = cache.GetOrCreate(key, entry => DoDBLookup(entry.Key));

例如,如果您想通读数据库。或者设置过期时间,根据key计算初始值等...