MVC中的MemoryCache的目的是什么? [英] What is the purpose of MemoryCache in MVC?

查看:183
本文介绍了MVC中的MemoryCache的目的是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对正确使用MemoryCache感到有些困惑.

I'm a bit confused on the proper usage of MemoryCache.

应该/可以将其用于加载静态信息以节省重复的通话吗? 是否应该/可以将其用于通过多种操作方法将数据持久化在视图上?

Should/can it be used to load static information to save on repeated calls? Should/can it be used to persist data on a view across several action methods?

我有一个实例,我不想使用数据存储来填充和持久保存整个视图中的数据.我开始使用工作正常的MemoryCache,但是我开始怀疑这是否是正确的方法.

I have an instance where I don't want to use the data store to populate and persist the data across my view. I started using the MemoryCache which works fine, however I'm starting to question if that was the correct approach.

我担心的是,如果我在同一页面上有多个用户使用同一个MemoryCache,会发生什么情况?

My concerns was what happens if I have several users on the same page using the same MemoryCache?

推荐答案

首先,

First of all, MemoryCache is part of the System.Runtime.Caching namespace. It can be used by MVC applications, but it is not limited to MVC applications.

注意:还有一个System.Web.Caching名称空间(较旧)只能与ASP.NET框架(包括MVC)一起使用.

NOTE: There is also a System.Web.Caching namespace (much older) that can only be used with the ASP.NET framework (including MVC).


应该/可以将其用于加载静态信息以节省重复的通话吗?

Should/can it be used to load static information to save on repeated calls?

是的

应该/可以通过多种操作方法将其用于持久保存视图中的数据吗?

Should/can it be used to persist data on a view across several action methods?

是的.如果您的视图使用相同的数据,则可以.或者,如果您的_Layout.cshtml页面上有需要缓存的数据,则可以在

Yes. If your views use the same data it can. Or if you have data that is on your _Layout.cshtml page that needs caching, it could be done in a global filter.

如果我在同一页面上有多个用户使用同一个MemoryCache,会发生什么情况?

what happens if I have several users on the same page using the same MemoryCache?

默认情况下,缓存在所有用户之间共享.它专门用于将数据保留在内存中,因此不必在每次请求时都从数据库中获取数据(例如,结帐页面上用于填充所有用户的下拉菜单中的状态名称列表).

Caching is shared between all users by default. It is specifically meant for keeping data in memory so it doesn't have to be fetched from the database on every request (for example, a list of state names on a checkout page for populating a dropdown for all users).

将频繁变化的数据缓存一两秒钟也是一个好主意,以防止大量并发请求成为对数据库的拒绝服务攻击.

It is also a good idea to cache data that changes frequently for a second or two to prevent a flood of concurrent requests from being a denial-of-service attack on your database.

缓存取决于唯一键.通过将用户名或ID用作密钥的一部分,可以将单个用户信息存储在缓存中.

Caching depends on a unique key. It is possible to store individual user information in the cache by making the user's name or ID part of the key.

var key = "MyFavoriteItems-" + this.User.Identity.Name;

警告::仅当您具有单个Web服务器时,此方法才有效.它不会扩展到多个Web服务器. 会话状态(用于单个用户内存存储)是一个更好的选择.可扩展的方法.但是,会话状态并不总是值得权衡.

Warning: This method works only if you have a single web server. It won't scale to multiple web servers. Session state (which is meant for individual user memory storage) is a more scalable approach. However, session state is not always worth the tradeoffs.


典型缓存模式

请注意,尽管MemoryCache是线程安全的,但将其与数据库调用结合使用可以使操作跨线程.如果没有锁定,则可能会导致对数据库的多个查询来在缓存过期时重新加载缓存.


Typical Caching Pattern

Note that although MemoryCache is thread-safe, using it in conjunction with a database call can make the operation cross threads. Without locking, it is possible that you might get several queries to the database to reload the cache when it expires.

因此,您应该使用双重检查锁定模式,以确保只有一个线程使其从数据库中重新加载缓存.

So, you should use a double-checked locking pattern to ensure only one thread makes it through to reload the cache from the database.

假设您有一个浪费每个请求的列表,因为每个用户进入特定页面时都需要该列表.

Let's say you have a list that is wasteful to get on every request because every user will need the list when they get to a specific page.

public IEnumerable<StateOrProvinceDto> GetStateOrProvinceList(string country)
{
    // Query the database to get the data...
}

要缓存此查询的结果,可以添加另一个具有双重检查的锁定模式的方法,然后使用它来调用原始方法.

To cache the result of this query, you can add another method with a double-checked locking pattern and use it to call your original method.

注意::一种常见的方法是使用装饰器模式来制作可以无缝缓存到您的API.

NOTE: A common approach is to use the decorator pattern to make the caching seamless to your API.

private ObjectCache _cache = MemoryCache.Default;
private object _lock = new object();

// NOTE: The country parameter would typically be a database key type,
// (normally int or Guid) but you could still use it to build a unique key using `.ToString()`.
public IEnumerable<StateOrProvinceDto> GetCachedStateOrProvinceList(string country)
{
    // Key can be any string, but it must be both 
    // unique across the cache and deterministic
    // for this function.
    var key = "GetCachedStateList" + country;

    // Try to get the object from the cache
    var stateOrProvinceList = _cache[key] as IEnumerable<StateOrProvinceDto>;

    // Check whether the value exists
    if (stateOrProvinceList == null)
    {
        lock (_lock)
        {
            // Try to get the object from the cache again
           stateOrProvinceList = _cache[key] as IEnumerable<StateOrProvinceDto>;

            // Double-check that another thread did 
            // not call the DB already and load the cache
            if (stateOrProvinceList == null)
            {
                // Get the list from the DB
                stateOrProvinceList = GetStateOrProvinceList()

                // Add the list to the cache
                _cache.Set(key, stateOrProvinceList, DateTimeOffset.Now.AddMinutes(5));
            }
        }
    }

    // Return the cached list
    return stateOrProvinceList;
}

因此,您调用GetCachedStateOrProvinceList,它将自动从缓存中获取列表,如果未缓存,则会自动将列表从数据库加载到缓存中.将仅允许一个线程调用数据库,其余线程将等待直到填充了缓存,然后在可用时从缓存中返回列表.

So, you call the GetCachedStateOrProvinceList and it will automatically get the list from the cache and if it is not cached will automatically load the list from the database into the cache. Only 1 thread will be allowed to call the database, the rest will wait until the cache is populated and then return the list from the cache once available.

请注意,每个国家/地区的州或省列表将被分别缓存.

Note also that the list of states or provinces for each country will be cached individually.

这篇关于MVC中的MemoryCache的目的是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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