2012-05-11 53 views
1

我在使用ASP.NET中的文件時遇到了圖像緩存問題。我的詳細解決方案是:使用ASP.NET中的文件進行圖像緩存問題

  • 對於第一個請求:我檢查圖像文件不存在,並將圖像文件寫入硬盤。之後,返回文件瀏覽器

  • 對於以後的請求的URL:該函數只是返回文件的網址到瀏覽器

我的問題是:有時與第1請求,瀏覽器無法從url中獲取圖像數據並導致404 - File Not Found錯誤。我認爲這可能是因爲文件已被寫入,但尚未準備好從瀏覽器中檢索,但在代碼中,我使用位圖&的「using statement」和「Dispose method」來確保所有內容都準備好從瀏覽器訪問。

在更多的細節,我現在用的是類似的解決方案,如NopCommerce:

lock (s_lock) { ........... 
using (var stream = new MemoryStream(LoadPictureBinary(picture))) { 
    using(var b = new Bitmap(stream)){ 
    using(var newBitMap = new Bitmap(newSize.Width, newSize.Height)){ 
    ....................... 
    newBitMap.Save(
     Path.Combine(this.LocalThumbImagePath, localFilename), ici, ep); 
    } 
    } 
} 
} // end lock 

return url; 

更多信息:你可以在http://nopcommerce.codeplex.com/SourceControl/changeset/view/9125b9a7fafe#src%2fLibraries%2fNop.Services%2fMedia%2fPictureService.cs查看完整的代碼(請搜索GetPictureUrl()函數)

+0

「將文件的url返回給瀏覽器」 - 它是否爲302重定向?或者你「第一次請求」是指請求到其他頁面,而不是圖像? –

+0

您沒有發佈足夠的代碼來診斷爲什麼第一個請求返回沒有圖像準備好的URL。您所問的錯誤是在您剔除的代碼中。也就是說,你在@Aristos的回答中提到了一個主要的線程錯誤。 –

+0

嗨克里斯,我添加了鏈接到問題的完整源代碼。有空時請回顧一下。提前致謝。 –

回答

2

這是當我看到多個請求一起發生在同一圖像時的情況。

對於這種情況,鎖是不夠的,你需要使用互斥鎖來鎖定所有線程和所有請求的過程。

所以我的建議是要改變lock,與mutex並使用映像名稱,或名稱圖像的代碼互斥不作任何鎖定,並且是要任何圖像製作,但只有一個是由互斥體上的名稱定義的。所以用互斥體改變鎖,然後看看這個問題是否仍然存在。

一提示:互斥名稱在大小和字符上有一些限制。如果您使用圖像文件名作爲互斥體的名稱,請確保它已被互斥體接受。

+0

+1使用Mutext縮小鎖定範圍。 –

+0

是的 - 如果這段代碼曾經看到一個空的圖像緩存的高負載,它會很快通過線程池,每個線程都卡在這個鎖中,等待每個線程完成圖像寫操作。你需要一個Mutex,但你也可能想在客戶端和服務器上的一個工作隊列上進行異步操作,而不是在ASP.Net請求線程上加鎖。 –

0

移動檢查文件存在與文件創建時相同的s_lock。應該用部分完成的文件解決問題(如果是問題)。

如果修復 - 使用@Aristos建議使用命名的Mutext替換鎖定(監視器)以將鎖定範圍鎖定到單個文件(如果您的站點預計負載很重)。