2013-08-22 54 views
0

我正在處理.NET HTTP處理程序(使用IsReusable設置爲true)以基於指定的ID返回圖像。傳遞的URL看起來像這樣ReadImage.ashx?id=N。一旦手柄接收它需要的ID,並期待在先前Base64編碼圖像的HTTP緩存,這樣的要求:HTTP圖像處理程序有時無法返回圖像

byte[] image; 
if (context.Cache["image_" + id] != null) 
{ 
    image = Convert.FromBase64String(context.Cache["image_" + id].ToString()); 
} 

如果它不存在,則進入從數據庫文件名,請閱讀從磁盤文件,它編碼爲Base64和字節存儲在image最後緩存圖像20分鐘這樣的:

else 
{ 
    var dbImage = m_database.Images.Single(i => i.Id.Equals(id)); 
    string filePath = context.Server.MapPath(string.Format("~/{base path}/{0}", dbImage.Filename)); 
    using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) 
    { 
     image = new byte[fs.Length]; 
     fs.Read(image, 0, image.Length); 
     context.Cache.Add("image_" + dbImage.Id, Convert.ToBase64String(image), null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(20), CacheItemPriority.Normal, null); 
    } 
} 

然後我終於BinaryWriteimage緩衝器當前上下文的輸出流:

context.Response.ContentType = "image/png"; 
context.Response.BinaryWrite(image); 
context.Response.Flush(); 

現在,這一切都工作得很好 - 但並非所有的時間。我偶爾會得到一張破碎的圖像,但刷新後圖像(99%的時間)在那裏。

看着Chrome的調試器中的網絡流量,我可以看到我的處理程序正在返回text/html,如果圖像中斷,而不是image/png,它應該是。我試過在try-catch中包裝我的處理程序並記錄異常詳細信息,但它什麼都不做 - 它只是繼續向請求頁面返回垃圾。

image handler issue

到目前爲止,我已經試過幾件事情:

  1. 緩衝了我的image在4096塊。
  2. 創建一個Bitmap對象並返回它。
  3. 徹底刪除緩存(如果我這樣做,它會更頻繁地失敗)。
  4. 嘗試捕獲異常並記錄它們(它從不拋出異常)。

我是否錯過了這裏的明顯?我有點難住,任何人有任何建議?

回答

0

不是一個解決方案,而是一個更好的解決方法。

我決定爲它創建一個MVC動作,而不是使用通用處理程序。這是行動,我沒有一次失敗,似乎要快得多。

[HttpGet] 
public ActionResult GetImage(int id) 
{ 
    byte[] buffer; 
    if (HttpContext.Cache["image_" + id] == null) 
    { 
     var dbMediaItem = m_database.MediaItems.Single(i => i.Id.Equals(id)); 
     string path = string.Format(Server.MapPath("~/{base path}/{0}"), dbMediaItem.Filename); 
     using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) 
     { 
      buffer = new byte[fs.Length]; 
      fs.Read(buffer, 0, buffer.Length); 
      HttpContext.Cache.Add("image_" + id, Convert.ToBase64String(buffer), null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(20), CacheItemPriority.Normal, null); 
     } 
    } 
    else 
    { 
     buffer = Convert.FromBase64String(HttpContext.Cache["image_" + id].ToString()); 
    } 
    return base.File(buffer, "image/png"); 
} 
1

只是我的猜測。這個問題我橫亙在下面的代碼:

if (context.Cache["image_" + id] != null) 
{ 
    image = Convert.FromBase64String(context.Cache["image_" + id].ToString()); 
} 

緩存可以在任何時間變得無效。很有可能在if語句計算結果爲true後,緩存項立即變爲無效,最終第二個get將會變爲空。最好這樣做(不是100%肯定):

var base64String = context.Cache["image_" + id].ToString(); 
if (base64String != null) image = ... 
+0

不幸的是,這個問題仍然存在(儘管稍差),如果我完全刪除緩存,謝謝你的提醒。 –