问题标签 [memorycache]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - AddOrGetExisting 不考虑过期
我正在使用(.NET 4.5)MemoryCache,结合SlidingExpiration。
我注意到方法 .AddOrGetExisting() 似乎并没有牢记过期,而 .Get() 确实。
单元测试:
问题:
这是.AddOrGetExisting()的预期行为吗?
我可以回退到 .Get(),然后,如果为 null,则使用 .Add()。
但是,因此我必须实现自己的锁定以确保线程安全。
c# - 添加后项目不在缓存中。使用 Web Api 和内存缓存
当我将项目添加到内存缓存时,下一个请求时它是空的。任何人都可以帮助我吗?
这是我的缓存服务:
在此处向 ninject 注册我的服务:
然后我在查询服务中使用下面的缓存服务:
然后将此服务注入我的控制器:
任何想法为什么我可以看到项目添加成功但是当我尝试第二次检索它们时缓存中没有任何内容?我假设每个请求都会实例化内存缓存?我怎样才能阻止这种情况,并允许我的缓存对象持续存在?
c# - 在 asp.net mvc 应用程序中使用 memorycache 每次都会创建它
我已经围绕 memorycache 创建了一个包装器和具体类,我在它的constrcutor中设置了 memoryCache
然后统一获取内存缓存的一个实例,我使用了ContainerControlledLifetimeManager
我使用以下代码在我的 homeController 中设置缓存
但是在将其上传到 iis 缓存后有时会变空。
检查
为什么它会为空?我该怎么办?
c# - 这是清除 C# MemoryCache 的好方法吗?
我已经阅读了有关在 C# 中清除 MemoryCache 的问题和答案。有很多建议,例如:1.枚举缓存,并删除所有项目-根据其他人的说法,这不好,让枚举器锁定整个事物,并且会发生各种启示,引用文档的一部分,我没有找到,并显示警告,我无法重现。无论如何,我认为这不是一个非常有效的解决方案。
将键存储在单独的集合中,并迭代该集合,以从缓存中删除项目。- 除了这听起来不是很安全,它听起来也不是很有效。
处理旧缓存,并创建一个新缓存 - 这听起来不错,这是一个显而易见的问题,并在一些评论中指出,对旧缓存的现有引用可能会带来问题。当然,操作的顺序很重要,你必须为旧的保存一个参考,创建一个新的来代替旧的,然后处理旧的 - 似乎不是每个人都注意到这个细微差别。
所以现在怎么办?我的一位同事建议使用 MemoryCache 解决我的问题,他将缓存对象包装在另一个类中,它可以选择获取密钥(如果需要,从数据库加载它)、删除密钥或清除缓存. 前两个现在不重要,第三个很有趣。我为此使用了第三种解决方案,按照“保证,除了我自己的实现之外,没有对 MemoryCache 对象的任何额外引用”。所以相关代码是:
构造函数:
清除缓存:
_cache 是私有的 MemoryCache 对象。
这会在多线程环境中引起问题吗?我对并行调用 read 和 dispose 有一些担忧。我是否应该实现某种锁定机制,允许并发读取,但会导致清除缓存功能等待当前读取在缓存上完成?
我的猜测是肯定的,这是实现这一点所必需的,但我想在开始之前获得一些见解。
罗伯特
编辑 1 关于 Voo 的回答: 可以保证,“包装器”(MyCache)之外的任何人都不会获得对 _cache 对象的引用。我的担心是这样的:
除了仍在使用旧缓存的 T2 线程之外,这不是首选,但我可以忍受,是否存在 Get 方法以某种方式访问处于已处置状态的旧缓存的情况,或者在没有数据的情况下读取新缓存?
想象一下 GetOrReadFromDb 函数是这样的:
我认为有可能,控制从读取线程中移除,并给予清除,例如在从 db 读取之后,在返回 _chache[key] 值之前,这可能会导致问题。这是一个真正的问题吗?
c# - Windows 应用程序的持久内存缓存?
我正在寻找即使在 Windows 窗体应用程序关闭后仍然存在的内存缓存。到目前为止,我考虑的唯一选择是在关闭应用程序之前使用二进制格式化程序将内存缓存对象写入文件。
是否有可以通过 NuGet 使用的持久内存缓存?
编辑:我们在“映射”表中有大约 3000 万行,每 1 小时需要查询大约 100,000 次。需要缓存背后的想法是避免用查询堆积数据库。
映射表的结构:
我们每小时将解析大约 100,000 个配置文件。作为此解析的一部分,我们将根据他们的邮政编码查询时区偏移量,并使用它来计算时间范围。
最好的方法是什么?
c# - 在 Finalizer 中处理 MemoryCache 会引发 AccessViolationException
编辑 有关更多详细信息,请参阅问题底部的编辑说明。
原始问题
我有一个 CacheWrapper 类,它在MemoryCache
内部创建并保存 .NET 类的一个实例。
MemoryCache
将自身挂钩到 AppDomain 事件中,因此除非明确处置,否则它永远不会被垃圾收集。您可以使用以下代码验证这一点:
由于这种行为,我相信我的 MemoryCache 实例应该被视为非托管资源。换句话说,我应该确保它在 CacheWrapper 的终结器中被处理(CacheWrapper 本身就是 Disposable 遵循标准的 Dispose(bool) 模式)。
但是,我发现当我的代码作为 ASP.NET 应用程序的一部分运行时,这会导致问题。卸载应用程序域时,终结器在我的 CacheWrapper 类上运行。这反过来又会尝试处置该MemoryCache
实例。这是我遇到问题的地方。似乎Dispose
尝试从 IIS 加载一些配置信息,但失败了(可能是因为我正在卸载应用程序域,但我不确定。这是我的堆栈转储:
有什么已知的解决方案吗?我认为我确实需要MemoryCache
在终结器中处理它是正确的吗?
编辑
本文验证了 Dan Bryant 的回答,并讨论了许多有趣的细节。特别是,他介绍了 的情况StreamWriter
,它面临与我的情况类似的情况,因为它想在处理时刷新它的缓冲区。这篇文章是这样说的:
一般来说,终结器可能不会访问托管对象。然而,对于相当复杂的软件来说,对关闭逻辑的支持是必要的。Windows.Forms 命名空间使用 Application.Exit 处理此问题,它会启动有序关闭。在设计库组件时,有一种支持关闭逻辑的方法与现有的逻辑相似的 IDisposable 集成是很有帮助的(这避免了在没有任何内置语言支持的情况下定义 IShutdownable 接口)。这通常是通过在调用 IDisposable.Dispose 时支持有序关闭来完成的,并且在没有调用时支持中止关闭。如果可以使用终结器尽可能有序地关闭,那就更好了。
微软也遇到了这个问题。StreamWriter 类拥有一个 Stream 对象;StreamWriter.Close 将刷新其缓冲区,然后调用 Stream.Close。但是,如果 StreamWriter 未关闭,则其终结器无法刷新其缓冲区。微软通过不给 StreamWriter 终结器“解决”了这个问题,希望程序员会注意到丢失的数据并推断出他们的错误。这是需要关闭逻辑的完美示例。
综上所述,我认为应该可以使用 WeakReference 实现“托管终结”。基本上,让你的类在创建对象时注册一个对其自身的 WeakReference 和一个带有一些队列的 finalize 操作。然后,队列由后台线程或计时器监控,当它配对的 WeakReference 被收集时,它会调用适当的操作。当然,您必须小心,您的 finalize 操作不会无意中保留类本身,从而完全防止收集!
c# - 有什么办法可以将 MemoryCache 过期暂停一段时间?
我正在使用 .NET 的 MemoryCache 类在我的应用程序中缓存数据。在大多数应用程序的用例中,绝对和/或滑动过期缓存策略对我的应用程序非常有用。但是,在某些时间段,应用程序可能会启动一个长时间运行的进程,该进程不会更新任何应用程序数据。该过程通常很长,以至于缓存将过期并在此过程中清除缓存的数据,这是我真正希望数据保留在缓存中的时候。有什么方法可以暂时暂停 MemoryCache 的过期和/或清除?
我可以扔掉我所有的物品并一个一个地更改过期策略,但我担心我在缓存中有数十万甚至数百万的物品,这将无法从绩效视角。
一种想法是将项目放回 CacheEntryRemovedCallback 中的缓存中,但这似乎是您在与系统作斗争而不是使用它,并且不是线程安全的。
任何想法,将不胜感激。
c# - C# 中的 MemoryCache 意外驱逐
在我的生产服务器上,我有一个大量使用的 SQL Server 实例和我的应用程序,它是 ac# Windows 服务。我的服务在不同时间运行各种工作。它每 24 小时发送一封电子邮件,提供有关各种工作进度的最新信息。
代码通过检查内存缓存中的标志来确定是否发送电子邮件。代码如下所示:-
当我的主循环每分钟左右检查一次空条目时,我收到了很多电子邮件。就好像 Add 失败了,或者 item 被驱逐了?
我在一些地方读到,如果没有足够的可用内存,项目可能会被驱逐。发生这种情况时,维护脚本正在 SQL Server 中运行,并且盒子上的可用内存几乎为零。我关闭了一些我在服务器上运行的程序、chrome、SSMS 等,瞧,没有更多的日志条目或电子邮件。
由于我已将项目的过期时间明确设置为现在 + 24 小时,我希望它会在 24 小时内添加项目!
这里的解决方案是什么,我是否必须将 CacheItemPriority 设置为 NotRemoveable,然后在 24 小时后手动删除该项目?
有点违背了我如何使用缓存的意义,或者 NotRemovable 会与 AbsoluteExpirationDate 一起工作吗?
c# - 我应该如何填充 MemoryCache 而无需实例化要缓存的对象?
MemoryCache类公开了一个名为 .AddOrGetExisting 的方法,这是一种线程安全的方法来获取是否存在,如果不存在则添加。
NULL
如果缓存的对象不存在,则此方法返回。我想我理解它的价值,因为它向用户提供了关于它在缓存中存在的反馈。
我的缓存解析器如下所示:
我想要完成的是,除非需要,否则不会创建对象,如果需要,我不想构造它两次。
我担心的是,当我将.Value
我的Lazy
类型作为参数传递时,它可能会调用初始化程序,而不管该项目是否在缓存中找到。但是,如果我正确理解 JIT,它将传递方法的委托而不是调用它。
我应该如何实现这些目标:
- 如果对象初始化程序已存在于缓存中,则不要调用它
- 如果它不在缓存中,则只调用一次。