2010-10-18 22 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