2010-10-18 26 views
2

獲得一個位圖每當我試圖讓我從我得到的參數異常的情況下緩存的位圖。位圖是從緩存對象中轉換而來的,但內容已損壞。從緩存

拋出異常就行

ImageFormat imageFormat = bitmap.RawFormat; 

bitmap.RawFormat」扔類型的異常‘System.ArgumentException’

剛剛給我的消息‘參數無效’。

當我堅持在代碼看看緩存中的所有屬性報到相同的異常創建位圖斷點。

下面是從我的處理程序處理請求....

/// <summary> 
    /// Processes the image request. 
    /// </summary> 
    /// <param name="context">The httpContext handling the request.</param> 
    public void ProcessRequest(HttpContext context) 
    { 
     //write your handler implementation here. 
     if (!string.IsNullOrEmpty(context.Request.QueryString["file"])) 
     { 
      string file = context.Request.QueryString["file"]; 
      bool thumbnail = Convert.ToBoolean(context.Request.QueryString["thumb"]); 
      // Throw in some code to check width and height. 
      int width = Convert.ToInt32(context.Request.QueryString["width"]); 
      int height = Convert.ToInt32(context.Request.QueryString["height"]); 

      // Store our context key. 
      string key = file; 

      // Strip away our cache data value. 
      file = file.Substring(0, file.LastIndexOf("_", StringComparison.OrdinalIgnoreCase)); 

      OnServing(file); 

      try 
      { 
       //Check the cache for a file. 
       Bitmap bitmap = (Bitmap)context.Cache[key]; 
       if (bitmap != null) 
       { 
        ImageFormat imageFormat = bitmap.RawFormat; 
        // We've found something so lets serve that. 
        using (MemoryStream ms = new MemoryStream()) 
        { 
         bitmap.Save(ms, imageFormat); 
         context.Response.BinaryWrite(ms.ToArray()); 
        } 

       } 
       else 
       { 
        // Nothing found lets create a file. 
        // Lock the file to prevent access errors. 
        lock (this.syncRoot) 
        { 
         string path = HostingEnvironment.MapPath(String.Format("~/Images/{0}", file)); 
         FileInfo fi = new FileInfo(path); 
         if (fi.Exists) 
         { 
          using (Bitmap img = (Bitmap)Bitmap.FromFile(path)) 
          { 
           ImageFormat imageFormat = img.RawFormat; 
           if (thumbnail) 
           { 
            ImageEditor imageEditor = new ImageEditor(img); 
            Size size = new Size(width, height); 
            imageEditor.Resize(size, true); 
            imageEditor.FixGifColors(); 

            using (MemoryStream ms = new MemoryStream()) 
            { 
             imageEditor.Image.Save(ms, imageFormat); 

             // Add the file to the cache. 
             context.Cache.Insert(key, img, new System.Web.Caching.CacheDependency(path)); 
             imageEditor.Dispose(); 
             context.Response.BinaryWrite(ms.ToArray()); 
            } 
           } 
           else 
           { 
            using (MemoryStream ms = new MemoryStream()) 
            { 
             img.Save(ms, imageFormat); 

             // Add the file to the cache. 
             context.Cache.Insert(key, img, new System.Web.Caching.CacheDependency(path)); 
             context.Response.BinaryWrite(ms.ToArray()); 
            } 
           } 
           OnServed(file); 
          } 
         } 
         else 
         { 
          OnBadRequest(file); 
         } 
        } 
       } 
      } 
      catch (Exception ex) 
      { 
       throw ex; 
       // OnBadRequest(ex.Message); 
       // return a default empty file here.      
      } 

     } 

    } 

任何幫助將不勝感激。

+0

您能否發佈異常的確切詳情?它出現什麼樣的線路和異常的信息是什麼? – 2010-10-18 10:14:43

+0

我已經用異常詳細信息更新了問題。 – 2010-10-18 10:25:15

回答

3

我建議不要持有到資源的時間超過在需要他們。

至於上面的代碼中,問題是,你沒有創建一個新的位圖,當你得到一個保存的圖像 - 你檢索一個現有的從緩存中,這有可能已經被處理掉。請嘗試使用以下代碼:

// When saving to the cache, use a MemoryStream to save off the bitmap as an array of bytes 
using (MemoryStream ms = new MemoryStream()) { 
    bitmap.Save(ms, bitmap.RawFormat); 
    context.Cache.Insert(key, (byte[])ms.ToArray(), ... 
    ... 
} 

... 

// When retrieving, create a new Bitmap based on the bytes retrieved from the cached array 
if (context.Cache[key] != null) { 
    using (MemoryStream ms = new MemoryStream((byte[])context.Cache[key])) { 
     using (Bitmap bmp = new Bitmap(ms)) { 
      bmp.Save(context.Response.OutputStream ... 
... 
+0

就是這樣。現在工作一種治療。乾杯 – 2010-10-18 14:14:10

+0

非常好!很高興你有它的工作:D – 2010-10-18 14:48:01

2

當緩存您在使用塊內這樣的圖像對象:

using (Bitmap img = (Bitmap)Bitmap.FromFile(path)) 
{ 
    // ... lots of code 

    // Add the file to the cache. 
    context.Cache.Insert(key, img, new System.Web.Caching.CacheDependency(path)); 

    // ... other code 
} 

在此使用塊的結尾,您的位圖將被佈置。因此您不能再使用它。如果要從緩存中再次使用位圖,則需要停止位圖處理。

但是,如果您只是想要在緩存時再次返回相同的圖像,那麼只需緩存MemoryStream可能會更簡單,更高效 - 它不會遭受任何無形的GDI +關係,並且幾乎可以返回處理緩存命中。

+0

這似乎沒有解決它。我更改了代碼並清除了緩存,但仍然收到相同的錯誤。 – 2010-10-18 10:44:40

+0

如果Bitmap對象不喜歡被緩存,而是嘗試緩存MemoryStream - 無論如何這可能會更好。 – 2010-10-18 10:57:01

+0

這樣比較好。我改變它來緩存內存流,並刪除了流的使用語句,我現在唯一擔心的是這些流是未處理的。你認爲垃圾收集器會處理這個問題還是需要重構? – 2010-10-18 12:32:40