【问题标题】:Increase counter inside IMemoryCache增加 IMemoryCache 内的计数器
【发布时间】:2021-12-18 12:42:23
【问题描述】:

我有以下情况:

//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);
}

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

我该怎么做?我知道GetOrCreate(object, Func&lt;&gt;)的方法,但我不知道如何实现。

【问题讨论】:

    标签: c# asp.net caching


    【解决方案1】:

    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&lt;ICacheEntry, TItem&gt;,它转换为这种形式的代表:TItem FunctionName(ICacheEntry entry)。因此,一个函数采用 ICacheEntry 类型的参数并返回您的值应为的任何类型。

    _ =&gt; 0 与此匹配,因为它是一个 Func,它忽略输入参数并只返回 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);
        }
    }
    

    生产

    未找到密钥 1 2

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

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

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

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

    【讨论】:

    • 您的 GetOrCreate 方法对我不起作用。检索到的值(对于同一个键)始终为 0。
    • 您可以通过尝试使用它来更新您的问题,我们会解决的。
    猜你喜欢
    • 2017-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多