我对HttpResponse.RemoveOutputCacheItem()
调用提供的粒度感到有点困惑。我有兴趣在动态生成的图像上执行一些输出缓存,并希望至少使用参数来改变输出缓存(为了参数的缘故,我们称它们为'id'和'size'。)
所以,例如:
/Image/User?id=1 /Image/User?id=1&size=1 /Image/User?id=1&size=2
将单独缓存。
当给定用户改变他们的照片时;我想要使该用户ID的所有输出缓存项无效(无论大小)。 This question回答了我关于单个特定参数的问题。但是..如果不考虑大小参数,我将如何为用户刷新所有缓存的响应? (我们假设我不会提前知道'size'的所有可能值。)
我最喜欢这样的事情:
HttpResponse.RemoveOutputCacheItem("/Image/User?id=1&size=*"); //wishful thinking
有人能指出我正确的方向吗?
修改
@JcMalta提出了一个很有前途的解决方案,但是我找不到为输出缓存中的项目公开的适当集合。一个可行的解决方案可能包括类似于他提出的操作,如果它存在于某处。
答案 0 :(得分:3)
输出缓存具有“缓存依赖关系”的概念,可能就是您要查找的内容。
.NET具有FileCacheDependency,这意味着如果磁盘上的文件发生更改,则缓存项会自动失效,而当MSSQL数据库中的数据发生更改时,会使SqlCacheDependency失效。您还可以编写自定义缓存依赖项。
HttpResponse有一堆名为Add * Dependency / ies的方法让你使用它。
例如,如果您的图片是基于磁盘上的文件,那么为调整大小的图像提供服务的处理程序可能会说:
HttpResponse.AddFileDependency(@"C:\images\user" + userId + ".jpg");
这会为您的响应注册一个依赖项。当您的响应添加到输出缓存时,任何依赖项都会随之发生。当依赖项更改时,缓存项将自动失效。
如果您的图像基于文件或SQL数据,这可能会为您提供开箱即用的功能。
您还可以使用HttpResponse.AddCacheItemDependency使一个缓存项依赖于另一个缓存项。如果您知道原始图像URL“/ Image / User?id = 1”将始终被缓存,那么您可以使调整大小的图像依赖于原始图像,并且原始图像上的HttpResponse.RemoveOutputCacheItem()将清除所有这些图像。如果原始图像并不总是被缓存(也许没有人请求原始图像,只有缩略图),那么我认为这不会起作用。
内置缓存依赖项工作的原因是Windows和SQL Server都有内置API来通知文件或数据的更改。内置缓存依赖项是围绕它们的包装器。但如果这些都不合适,那么你的最后一种方法就是为了你自己的目的而实现类似的东西。
基本思想(未经测试)是子类CacheDependency,我们称之为PictureCacheDependency。
您需要设置某种侦听器/观察者模式,以便在用户编辑其图片时,图片编辑代码可以告知任何相关的PictureCacheDependency对象图片已更改。当发生这种情况时,PictureCacheDependency应该调用base.NotifyDependencyChanged,框架将负责其余的工作。
您可能将PictureCacheDependency构造函数注册在静态事件字典中,并使用用户ID作为键。无论你接近它,一定要覆盖CacheDependency.DependencyDispose来释放任何引用,否则你会泄漏内存。
答案 1 :(得分:1)
真的,这不是我的头脑......但也许是在正确的方向:
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);
}
}