2010-08-13 56 views
4

我對調用HttpResponse.RemoveOutputCacheItem()提供的粒度有些困惑。我有興趣在動態生成的圖像上執行一些輸出緩存,並且希望至少使用參數來改變輸出緩存(爲了參數的緣故,我們稱它們爲'id'和'size')。使asp.net mvc輸出緩存的部分無效 - 具有不同粒度級別

那麼,例如:

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

會需單獨緩存。

當給定用戶改變他們的圖片時;我想要使​​該用戶標識的所有輸出緩存項無效(不管大小)。 This question解答了我關於單個特定參數的問題。但是..我會怎麼去沖洗一個用戶的所有緩存響應而不考慮大小參數? (讓我們假設我不會提前知道'大小'的所有可能值)。

我非常喜歡做這樣的事情:

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

任何人都可以點我在正確的方向?

編輯

@JcMalta提出了一個可行的解決方案,但我不能找到暴露在輸出緩存項適當的集合。一個可行的解決方案可能包括一個類似於他所建議的操作,如果這存在的地方。

回答

3

輸出緩存具有「緩存依賴」的概念,可能是你在找什麼。

.NET有一個FileCacheDependency,它意味着如果磁盤上的文件發生更改,緩存項會自動失效,而SqlCacheDependency會在MSSQL數據庫中的數據更改時使對象無效。您也可以編寫自定義緩存依賴項。

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來釋放任何引用,否則你會泄漏內存。

+0

感謝您的答覆; HttpResponse.AddCacheItemDependency對我來說似乎是個不錯的選擇。 – DanP 2010-08-20 11:05:19

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); 
    } 
} 
+0

只是要清楚;我的目標是輸出緩存,而不是httpcache,但前提是一樣的... – DanP 2010-08-13 21:32:13

+0

不幸的是,據我所知,合適的集合沒有公開輸出緩存,所以我不能使用這個方法(好建議,雖然)... – DanP 2010-08-16 13:47:26

相關問題