我正在设置我的内存缓存,如下所示:

DataCache = new MemoryCache(new MemoryCacheOptions
{
    ExpirationScanFrequency = TimeSpan.FromMinutes(5)
});
CacheOptions = new MemoryCacheEntryOptions
{
    AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5)
};

然后按如下方式使用它:

DataCache.Set(Keys.Users, listAllUsers, CacheOptions);

这样对吗?我觉得很奇怪,我必须把它放在两个地方.

推荐答案

高速缓存线的到期有两个部分(按时间):

  1. 缓存线"到期"之前的时间跨度.在这种情况下,这意味着它有资格被移除(也称为"驱逐").这是一件被动的事情--没有一段代码主动地将缓存线从有效设置为过期,它只是一个变得比"现在"更"旧"的时间戳.

  2. 执行活动进程的周期时间,该周期扫描缓存中的过期缓存行并将其删除.

两者的组合导致单个高速缓存线的实际到期和移除时间跨度.如果我们举一个从插入时间起5分钟到期的例子,并且每15秒扫描一次周期,那么在最好的(或短的)情况下,该周期正好运行,因此在同一时间发生到期,并且在5分钟之后立即移除该行.最糟糕(或最长)的情况是扫描周期正好在到期前结束,并且高速缓存线持续5分15秒(所有+/-系统计时/时钟不准确).

如果将两者都设置为5分钟,则最终将得到单个缓存线,其存活时间在5分钟到10分钟之间.(从统计学上讲,假设插入是正态分布的.)

对于这个答案的future 读者:请记住这important notice in the docs

There are two MemoryCache classes within .NET,一个在System.Rounme.Cating命名空间中,另一个在Microsoft.Extensions.Caching命名空间中

(我强调)

还请注意,还有一个SlidingExpation,它在问题中有not个问题,在这个答案中也没有.当高速缓存线命中时,SlidingExpation将延长到期阈值.如果使用它,建议同时设置滑动和绝对,以避免频繁命中的高速缓存线never实际上被逐出(这会导致问题).

Csharp相关问答推荐

c#处理大量tcp连接

如何修改扩展方法以在C#中的DataTable转换中包括/排除特定列?

.NET通过版本自动增量设置包版本

ß != ss与ICU进行不区分大小写的比较

如何将字节数组转换为字符串并返回?

ASP.NET核心结果.文件vs结果.流

. NET 8使用COM向VB6公开

EF Core. Income和. AsNoTracking正确用法

始终保留数组中的最后N个值,丢弃最老的

SignalR客户端不会打印队列位置'

在C#中,DirectoryEntry返回空AuditRules集合,即使审计规则确实存在

如何在不考虑年份的情况下判断日期时间是否在某个日期范围内?

Mongo作为.NET中Testcontainers的副本集

在允许溢出的情况下将小数转换为长

Rx.Net窗口内部可观测数据提前完成

在具有不同属性名称的两个类之间创建关系

如何在ASP.NET Core8中启用REST应用程序的序列化?

Linux Docker上的.NET6在某个时间抛出后,在加密操作期间发生System.Security.Cryptography.CryptographicException:错误

为什么Azure函数(独立工作进程)索引失败?使用Azure App配置的CosmosDbTrigger绑定失败,未解析为值

如何使用LINQ在C#中填充列表列表?