如何处理使用的MemoryCache昂贵的建设运营? [英] How to deal with costly building operations using MemoryCache?

查看:179
本文介绍了如何处理使用的MemoryCache昂贵的建设运营?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个ASP.NET MVC项目,我们有需要的资源和时间来建立良好的数据量的几个实例。我们要对它们进行缓存。

On an ASP.NET MVC project we have several instances of data that requires good amount of resources and time to build. We want to cache them.

的MemoryCache 提供了一定程度的线程安全的,但不足以避免并行运行的建筑规范的多个实例。下面是一个例子:

MemoryCache provides certain level of thread-safety but not enough to avoid running multiple instances of building code in parallel. Here is an example:

var data = cache["key"];
if(data == null)
{
  data = buildDataUsingGoodAmountOfResources();
  cache["key"] = data;
}

你可以在一个繁忙的网站上看到数百个线程可以去里面的,如果声明同时直到数据被构建和使建筑物操作更慢,不必要地消耗了服务器资源。

As you can see on a busy website hundreds of threads could go inside the if statement simultaneously until the data is built and make the building operation even slower, unnecessarily consuming the server resources.

有是一个原子 AddOrGetExisting 实施情况的MemoryCache但它错误地要求值设置,而不是代码来检索设定值,我想呈现给定的方法几乎完全无用。

There is an atomic AddOrGetExisting implementation in MemoryCache but it incorrectly requires "value to set" instead of "code to retrieve the value to set" which I think renders the given method almost completely useless.

我们已经用我们周围的MemoryCache自己的临时棚架得到它的权利但是它需要显式的锁定取值。它的使用繁琐每进入锁定的对象和我们通常通过共享锁的对象是远远不够理想脱身。 。这让我觉得理由来避免这种习惯可能是故意的。

We have been using our own ad-hoc scaffolding around MemoryCache to get it right however it requires explicit locks. It's cumbersome to use per-entry lock objects and we usually get away by sharing lock objects which is far from ideal. That made me think that reasons to avoid such convention could be intentional.

所以,我有两个问题:


  • 它是一个更好的做法,不要锁定建筑规范? (这可能已经被证明更适应一个,我不知道)

  • Is it a better practice not to lock building code? (That could have been proven more responsive for one, I wonder)

什么是实现每个入口锁定为的MemoryCache这样一个锁的正确方法?强烈的冲动,用字符串作为锁定对象在.NET锁定101辞退。

What's the right way to achieve per-entry locking for MemoryCache for such a lock? The strong urge to use key string as the lock object is dismissed at ".NET locking 101".

推荐答案

我们结合懒<解决了这个问题, ; T> AddOrGetExisting 来避免需要完全锁定对象。下面是一个示例代码(使用无限到期):

We solved this issue by combining Lazy<T> with AddOrGetExisting to avoid a need for a lock object completely. Here is a sample code (which uses infinite expiration):

public T GetFromCache<T>(string key, Func<T> valueFactory) 
{
    var newValue = new Lazy<T>(valueFactory);
    // the line belows returns existing item or adds the new value if it doesn't exist
    var value = (Lazy<T>)cache.AddOrGetExisting(key, newValue, MemoryCache.InfiniteExpiration);
    return (value ?? newValue).Value; // Lazy<T> handles the locking itself
}

这是不完整的。还有像异常缓存,所以你必须决定你想要做的情况下,你的valueFactory抛出异常陷阱是什么。的优点之一,不过,是缓存空值太的能力。

That's not complete. There are gotchas like "exception caching" so you have to decide about what you want to do in case your valueFactory throws exception. One of the advantages, though, is the ability to cache null values too.

这篇关于如何处理使用的MemoryCache昂贵的建设运营?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆