【问题标题】:MemoryCache get/set and assigning to variableMemoryCache 获取/设置并分配给变量
【发布时间】:2018-03-02 16:30:06
【问题描述】:

我一直在本地测试一些代码并阅读了相当多的 SO 帖子,但我仍然有点困惑 MemoryCache 在某些情况下是如何工作的。所以问题与以下代码有关:

 class Program
{

    static void Main(string[] args)
    {
        var test = new Test();
        test.TestingMethod();
    }

}

public class Test
{
    private readonly MemoryCache MemoryCache = MemoryCache.Default;
    private CacheItemPolicy policy = null;
    private CacheEntryRemovedCallback callback = null;

    public void TestingMethod()
    {
        var ints = new List<int>();
        for (var i = 0; i <= 1000; i++)
        {
            ints.Add(i);
        }

        callback = this.MyCachedItemRemovedCallback;
        policy = new CacheItemPolicy
        {
            Priority = CacheItemPriority.Default,
            AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(2),
            RemovedCallback = callback
        };

        MemoryCache.Set("ints", ints, policy);
        var intsCached = (List<int>) MemoryCache.Get("ints");
        Task.Delay(TimeSpan.FromSeconds(15)).Wait();
        MemoryCache.Set("ints", new List<int>() {1}, policy);

        foreach (var intCached in intsCached)
        {
            Console.WriteLine(intCached);
        }
        Console.ReadLine();
    }

    void MyCachedItemRemovedCallback(CacheEntryRemovedArguments arguments)
    {
        Console.WriteLine("Expired");
    }
}

在这个 TestMethod 的控制台输出中,我得到了 已到期 1 - 1000 分行

为什么我会得到 1-1000 而不是我们在到期后设置的 1?这个列表不是引用同一个 ref 吗?

【问题讨论】:

  • 仅更新到我的主要问题
  • 此行为与 MemoryCache 无关。您已将包含 1000 个项目的列表存储到变量 intsCached 中。就这样。其他一切都是噪音。如果您从 MemoryCache 重新获取并迭代该集合,它将有 1 个项目。
  • 这不是对内存缓存列表的引用吗?这不是我读过的内存缓存中存储的内容的副本?
  • 它是对曾经也存储在 MemoryCache 中但不再存在的列表的引用。

标签: c# multithreading asynchronous caching thread-safety


【解决方案1】:

MemoryCache(或任何其他存储值的实体)在将同名条目设置为不同值时不会神奇地更新列表的内容。 IE。如果你改用MemoryCache.Set("ints", 42, policy); 怎么办?

看起来您希望值 (intsCached) 在分配给它很久之后才被计算:

  var intsCached = (List<int>) MemoryCache.Get("ints");

intsCached 在该行计算,不再知道它来自哪里。

如果您希望“变量”记住它的来源并始终从该位置获取最新值 - 每次都使用 Func 计算它:

  Func<List<int>> intsCached = () => (List<int>) MemoryCache.Get("ints");
  ...
  foreach (var intCached in intsCached()) 
  ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-27
    • 1970-01-01
    • 2021-02-22
    • 2018-08-22
    • 2018-08-10
    • 1970-01-01
    • 2019-05-24
    • 2015-08-24
    相关资源
    最近更新 更多