gpt4 book ai didi

c# - MVC中MemoryCache的作用是什么?

转载 作者:可可西里 更新时间:2023-11-01 08:34:31 25 4
gpt4 key购买 nike

我对 MemoryCache 的正确使用有点困惑。

它应该/可以用于加载静态信息以节省重复调用吗?它应该/可以用于跨多个操作方法在 View 上持久保存数据吗?

我有一个实例,我不想使用数据存储在我的 View 中填充和保留数据。我开始使用工作正常的 MemoryCache,但是我开始质疑这是否是正确的方法。

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

最佳答案

首先,MemoryCacheSystem.Runtime.Caching 命名空间的一部分。它可以被 MVC 应用程序使用,但不限于 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?

是的。如果您的 View 使用相同的数据,它可以。或者,如果您的 _Layout.cshtml 页面上有需要缓存的数据,可以在 global filter 中完成。 .

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

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

将频繁更改的数据缓存一两秒也是一个好主意,以防止大量并发请求对您的数据库造成拒绝服务攻击。

缓存取决于唯一的键。通过将用户名或 ID 作为 key 的一部分,可以将个人用户信息存储在缓存中。

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

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 是线程安全的,但将其与数据库调用结合使用可以使操作跨线程。如果没有锁定,您可能会多次查询数据库以在缓存过期时重新加载缓存。

因此,您应该使用 double-checked locking一种模式,以确保只有一个线程能够从数据库重新加载缓存。

假设您有一个列表,在每次请求时都获取该列表很浪费,因为每个用户在访问特定页面时都需要该列表。

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

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

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,它会自动从缓存中获取列表,如果没有缓存,则会自动将列表从数据库加载到缓存中。只允许 1 个线程调用数据库,其余线程将等到缓存被填充,然后在可用时从缓存中返回列表。

另请注意,每个国家/地区的州或省列表将单独缓存。

关于c# - MVC中MemoryCache的作用是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36646865/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com