代码之家  ›  专栏  ›  技术社区  ›  DanP

使部分asp.net mvc输出缓存-具有不同的粒度级别

  •  4
  • DanP  · 技术社区  · 14 年前

    我对 HttpResponse.RemoveOutputCacheItem()

    例如:

    /Image/User?id=1
    /Image/User?id=1&size=1
    /Image/User?id=1&size=2
    

    将分别缓存。

    当一个给定的用户改变他们的图片时,我想使该用户id的所有输出缓存项无效(不管大小)。 This question 回答了我关于一个特定参数的问题。但是..在不考虑size参数的情况下,如何刷新用户的所有缓存响应?(假设我不会提前知道所有可能的‘size’值)。

    HttpResponse.RemoveOutputCacheItem("/Image/User?id=1&size=*"); //wishful thinking

    有人能给我指出正确的方向吗?

    编辑

    @jcmat提出了一个很有前途的解决方案,但是我找不到为输出缓存中的项公开的适当集合。一个可行的解决方案可能包括一个类似于他提议的操作,如果这个操作存在于某个地方的话。

    2 回复  |  直到 7 年前
        1
  •  3
  •   David James    14 年前

    输出缓存有一个“缓存依赖项”的概念,这可能就是您要寻找的。

    .NET有一个FileCacheDependency,它意味着如果磁盘上的文件发生更改,缓存项将自动失效;还有一个SqlCacheDependency,它在MSSQL数据库中的数据发生更改时使对象失效。也可以编写自定义缓存依赖项。

    HttpResponse有一堆名为Add*Dependency/ies的方法让您可以使用它。

    HttpResponse.AddFileDependency(@"C:\images\user" + userId + ".jpg");
    

    这将为您的响应注册一个依赖项。当您的响应被添加到输出缓存时,任何依赖项都会随之发生。当依赖项更改时,缓存项将自动失效。

    如果您的图像是基于文件或SQL数据的,这可能对您非常有用。

    你也可以使用HttpResponse.AddCacheItemDependency使一个缓存项依赖于另一个缓存项。如果您知道您的原始图像URL“/图像/用户?id=1“将始终缓存,然后您可以使调整大小的图像依赖于原始图像,并且HttpResponse.RemoveOutputCacheItem()将清除所有原始文件。如果原始图像不总是被缓存(可能没有人请求原始图像,只有缩略图),那么我认为这样做行不通。

    内置缓存依赖项工作的原因是Windows和sqlserver都有内置api来通知对文件或数据的更改。内置的缓存依赖项是围绕这些依赖项的包装器。但是如果这两种方法都不合适,那么最后一种方法就是为自己的目的实现一个类似的东西。

    基本思想(未经测试)是将CacheDependency子类化,我们称之为PictureCacheDependency。

    您需要设置某种侦听器/观察者模式,以便当用户编辑其图片时,图片编辑代码可以告诉任何相关的PictureCacheDependency对象图片已更改。当发生这种情况时,PictureCacheDependency应该调用base.NotifyDependencyChanged已更改,框架将处理其余部分。

        2
  •  1
  •   JcMaltaDev    14 年前

    public void ClearCache( string myImagePrefix)
    {
        var cache = System.Web.HttpContext.Current.Cache;
    
        IDictionaryEnumerator enumerator = cache.GetEnumerator();
    
        while (enumerator.MoveNext())
        {
            string key = enumerator.Key.ToString();
            if( key.StartsWith( myImagePrefix)
               cache.Remove(key);
        }
    }