2014-01-27 28 views
3

在Razor中,我有一個循環給了我結果。在這種循環中,我有供應的圖像Url.Action:如何高效地在ASP.NET MVC中提供圖像

foreach (var i in Model.InventoryList) 
     { 
     <tr>     
      <td style="text-align: center;"><img alt="@i.ProductCode" src="@Url.Action("GetImageThumbnail", "ServiceRequest", new { ProductCode = i.ProductCode })" onclick="showGallery('@i.ProductCode');" /></td>     
     </tr> 
     } 

圖像服務取決於如果該特定行的形象存在。如果沒有,則提供替代圖像。

public ActionResult GetImageThumbnail(string productCode) 
    {    
     string filePath = "path_to_product.png"; 
     Size size = new Size(80, 50); 
     if (!System.IO.File.Exists(filePath)) 
     { 
      filePath = "No_image_available.png"; 
      size = new Size(50, 50); 
     } 
     using (MemoryStream ms = new MemoryStream()){ 
      Image image = Image.FromFile(filePath); 
      image = ImageHelpers.ResizeImage(image, size); 
      image.Save(ms, ImageHelpers.getImageFormat(filePath)); 
      return File(ms.ToArray(), ImageHelpers.getContentType(filePath)); 
     } 

    } 

現在這很好,如果有幾個結果,它的工作速度非常快。如果有成千上萬的結果,那麼在服務所有這些圖像實例時會有一定的放緩。有沒有更有效的方法來做到這一點?

我可能在模型中服務較少的結果,但這不是我在這個特定問題中所追求的目標。

+0

只是冒險猜測,但如果所有文件都在同一個物理驅動器上,您可能會看到IO瓶頸。一種可能的解決方案可能是每天或幾小時緩存圖像的存在或任何您希望更改的時間段,然後在提供圖像時檢查緩存而不是文件系統。 –

+1

像@DavidKhaykin說的那樣,緩存圖像。並緩存* resize *圖像;該操作相對昂貴。在瀏覽器中,延遲加載實際可見的圖像。考慮使用[可緩存的請求](http://stackoverflow.com/questions/3870726/force-refresh-of-cached-data/3870743#3870743)並設置緩存標頭以避免對同一圖像重複請求。 –

+0

爲什麼不把你的'string'屬性添加到'InventoryList'中,它將爲相應的圖片保存'url' –

回答

2

一些選項,我會說 -

  • 您可以對縮放後的圖像IIS的DiskCache Plugin。而不是立即進行所有調整大小的計算,而是在圖像創建本身時保存調整大小的圖像。稍後如果您不想調整大小的圖像,它可以在任何時間點刪除。
  • 其他一些插件,如SourceMemCache,OutputMemCache和SourceDiskCache也可用於DiskCache插件本身的IIS。
  • 或者,你可以寫所有的縮放後的圖像緩存提供商,如Redis.ioSquid
  • 嘗試重新設計你的頁面,我的意思是,即使它是一個畫廊頁,嘗試使用分頁,使一個畫廊中的成千上萬的圖像會在單個頁面上歸結爲幾十個。
相關問題