MemoryCache UpdateCallback无法正常工作

时间:2012-03-10 22:09:21

标签: c# caching .net-4.0 memorycache

我正在尝试创建与第三方API的连接池,并且如果它们未被使用,则连接在一个间隔后过期。当它们过期时,需要通过第三方API断开连接。

看起来MemoryCache(System.Runtime.Caching)会处理这个问题。但是,UpdateCallback似乎表现得很奇怪。

一个简单的LINQPad示例:

void Main()
{
    var cache = MemoryCache.Default;
    var policy = new CacheItemPolicy();
    policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(1);
    policy.UpdateCallback = Update;
    cache.Set("figkey", "fig", policy);

    Thread.Sleep(2000);

    object result = cache.Get("figkey");

    Console.WriteLine(result == null ? "null" : result);
}

public static void Update(CacheEntryUpdateArguments arguments)
{
    Console.WriteLine("got here");
}

如果我运行它,输出是:

fig

NOT 输出“来到这里”。

如果我注释掉以policy.UpdateCallback开头的行,则输出为:

null

我做错了什么?

如果有更好的方法来完成我的任务,我会接受其他建议。

3 个答案:

答案 0 :(得分:4)

我认为问题可能是Thread.Sleep,因为它们也会阻塞缓存,因为它们在同一个线程中运行。如果您尝试进行虚拟循环,则会触发更新处理程序:

var i = 0;
for (var j = 0; j < 10000000; j++)
{
    for (var k = 0; k < 1000000; k++)
        i++;
    i--;
}
Console.WriteLine(i);

而不是睡觉。

答案 1 :(得分:1)

只需在Main的末尾添加Console.ReadLine()或用Console.ReadLine()替换Sleep,启动样本并等待大约10秒钟。你会收到预期的消息。 MemoryCache里面的计时器有点慢。

但无论如何,MemoryCache肯定存在一个错误:分配UpdateCallback会改变行为,但不应该。

如果设置了AbsoluteExpiration并且传递了时间,则方法Get必须返回null,而不依赖于UpdateCallback的存在。

BTW,RemovedCallback不会改变行为。

答案 2 :(得分:0)

只需将睡眠时间增加到更大的值,您就会看到回调被执行。

通过计时器在另一个线程上发生过期(如果在回调中设置断点,则可以看到多少)。这就是睡眠或忙碌等待的原因。