C# MemoryCache内存项目无法缓存

neighbornet 2015-02-07 11:32:53
.NET4.0新增的System.Runtime.Caching,
希望使用其中的MemoryCache,缓存内存中的变量,并在该变量变化时,进行相应更新。

使用下面的代码进行测试,发现cache中一直没有想要的"cachedText",请教各位大侠,应如何解决此问题,多谢!

private void button2_Click(object sender, RoutedEventArgs e)
{
ObjectCache cache = MemoryCache.Default;

bool flag = cache.Contains("cachedText");
string content = cache["cachedText"] as string;

if (content == null)
{
CacheItemPolicy policy = new CacheItemPolicy();
policy.AbsoluteExpiration = DateTimeOffset.Now.AddHours(1);

content = textBox2.Text;

CacheItem item =new CacheItem("cachedText", content);


List<string> keys = new List<string> { "cachedText" };

policy.ChangeMonitors.Add(cache.CreateCacheEntryChangeMonitor(keys));

cache.Set(item, policy);
}

textBox1.Text = content;
}
...全文
726 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Forty2 2015-02-09
  • 打赏
  • 举报
回复
可能你误解了CacheEntryChangeMonitor。它不是用来监视‘变量变化’的,而是用来监视缓存条目的变化。 因为你登记的监视器监视一个尚不存在的条目,它一开始就认定有变化,变化就导致了缓存失效。 下面例子解释CacheEntryChangeMonitor的用法:

private void button2_Click(object sender, RoutedEventArgs e)
{
    ObjectCache cache = MemoryCache.Default;
    if (!cache.Contains("Master"))
    {
        cache.Add("Master", "Hello", DateTimeOffset.MaxValue);
    }

    bool flag = cache.Contains("cachedText");
    string content = cache["cachedText"] as string;

    if (content == null)
    {
        CacheItemPolicy policy = new CacheItemPolicy();
        policy.AbsoluteExpiration = DateTimeOffset.Now.AddHours(1);

        content = textBox2.Text;

        CacheItem item = new CacheItem("cachedText", content);


        List<string> keys = new List<string> { "Master" };

        policy.ChangeMonitors.Add(cache.CreateCacheEntryChangeMonitor(keys));

        cache.Set(item, policy);
    }

    textBox1.Text = content;
}

private void button3_Click(object sender, RoutedEventArgs e)
{
    MemoryCache.Default.Set("Master", "改变Master将导致任何‘依赖’于Master的条目失效", DateTimeOffset.MaxValue);
}
  • 打赏
  • 举报
回复
引用 5 楼 neighbornet 的回复:
我的目的是,只有当内存变量变化时,才更新缓存。否则直接读取缓存
设置缓存依赖项有其规范。没有现成的办法去监视“内存变化时”这种依赖项。顶多可以让成百上千的缓存单元依赖为另一个缓存单元,这样当这个缓存单元修改时,相关联的所有缓存单元就自动丢弃了。但是这就要求叫做“cachedText” 的缓存单元依赖于另外一个(比如说)叫做“最后结账时间”的缓存单元,而不是依赖“内存变量”。 除非你自己开发一个 CacheDepency(从这个类型继承,开发你自己的子类)才能依赖变量,但是这还是要考虑到效率问题。
  • 打赏
  • 举报
回复
如果缓存单元没有依赖项,缓存系统也会在必要时清楚缓存单元,例如在物理内存不足时,或者超过一定时间时,等等。因此你可以省略 policy 参数,不指定任何缓存依赖项。 指定缓存依赖项,这是为了保证缓存的数据是逻辑上一致的。例如csdn可以为每一个栏目的首页贴子集合和创建一个缓存单元。假设设置为“缓存10分钟”,但是可能当过了仅仅3分钟、仅仅有10万次访问之后,这个栏目有新的帖子或者回复信息发布了,于是这个缓存单元就是“脏的”了,需要自动清除。因此除了设置“缓存10分钟”以外,还要至少设置另外一个缓存依赖项以通知“栏目首页需要改变”(例如 SqlDepencency类似的根据数据库的依赖项,或者根据磁盘文件的依赖项,或者根据其它某个缓存单元的依赖项,等等)。 因此设置缓存依赖项是需要首先分析清楚业务逻辑、费心思进行设计的。可能一时半会儿找不到好办法来设置缓存依赖项,那就可以暂时不设置这个 policy。
neighbornet 2015-02-07
  • 打赏
  • 举报
回复
多谢指点! 我的目的是,只有当内存变量变化时,才更新缓存。否则直接读取缓存
  • 打赏
  • 举报
回复
人家的例子,是想“省得总是读取文件”,节省磁盘i/o时间。 而你的代码,我不知道怎么办好。因为你没有设计出你的“理由”和逻辑,而是“为了使用缓存而使用缓存”。还不如不用缓存。
  • 打赏
  • 举报
回复
msdn上的例子,content是一个string变量,放入"content"中的缓存单元时,指定“当cache.txt文件改变时,丢弃这个缓存单元”。 不要硬套它的代码。你的代码跟它的例子的逻辑不一样,无法仿照这个例子。
neighbornet 2015-02-07
  • 打赏
  • 举报
回复
引用 1 楼 sp1234 的回复:
一个缓存单元它的生命周期依赖于自己的生命周期,这是什么意思呢?这种 policy 完全无法理解。
刚开始学习Caching 下面是MSDN的例子,监测文件变化的。我是模仿此例子写的。 不过我的目的,是监视缓存的内存变量是否改变。请问,您有何宝贵建议吗?能否给个简单的例子?谢谢 private void button1_Click(object sender, RoutedEventArgs e) { ObjectCache cache = MemoryCache.Default; bool flag = cache.Contains("content"); string content = cache["content"] as string; if (content == null) { CacheItemPolicy policy = new CacheItemPolicy(); //policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(10); List<string> files = new List<string>(); files.Add(@"c:\cache.txt"); policy.ChangeMonitors.Add(new HostFileChangeMonitor(files)); content = File.ReadAllText(@"c:\cache.txt") + "\n" + DateTime.Now.ToString(); cache.Set("content", content, policy); } textBox1.Text = content; }
  • 打赏
  • 举报
回复
一个缓存单元它的生命周期依赖于自己的生命周期,这是什么意思呢?这种 policy 完全无法理解。

110,500

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧