2010-10-18 5 views
2

Chaque fois que j'essaie d'obtenir une image bitmap que j'ai mise en cache à partir du contexte, j'obtiens une exception d'argument. Le bitmap est moulé à partir de l'objet mis en cache mais son contenu est corrompu.Obtention d'un bitmap à partir du cache

L'exception est levée sur la ligne

ImageFormat imageFormat = bitmap.RawFormat; 

bitmap.RawFormat » a jeté une exception de type 'System.ArgumentException'

Ce qui me donne juste le message 'Paramètre non valide'.

Lorsque je place un point d'arrêt dans le code, regardez le bitmap créé à partir du cache, toutes les propriétés rapportent la même exception.

est ici la demande de processus de mon gestionnaire ....

/// <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.      
      } 

     } 

    } 

Toute aide serait grandement appréciée.

+0

Pourriez-vous nous communiquer les détails exacts de cette dérogation? Quelle ligne apparaît-elle et quel est le message de l'exception? –

+0

J'ai mis à jour la question avec les détails de l'exception. –

Répondre

3

Je peux vous recommander de ne pas conserver les ressources plus longtemps que nécessaire. Comme pour le code ci-dessus, le problème est que vous ne créez pas un nouveau bitmap lorsque vous obtenez une image enregistrée - vous en récupérez une existante à partir du cache, qui a probablement déjà été éliminée. Essayez d'utiliser ce qui suit à la place:

// 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

Ça y est. Travailler un régal maintenant. Salutations –

+0

Excellent! Je suis content que vous l'ayez réussi: D –

2

Lorsque vous mettez en cache l'objet d'image que vous le faites dans un bloc à l'aide:

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 
} 

A la fin de ce bloc à l'aide, votre bitmap sera éliminé. Par conséquent, vous ne pouvez plus l'utiliser. Vous devez arrêter de disposer de l'image bitmap si vous souhaitez l'utiliser à nouveau dans le cache. Cependant, étant donné que vous voulez simplement renvoyer la même image si elle est mise en cache, il peut être plus simple et plus efficace de simplement mettre en mémoire cache le MemoryStream - ceci ne subit aucun lien GDI + invisible et peut être renvoyé traitement sur un hit de cache.

+0

Cela ne semble pas l'avoir corrigé. J'ai changé le code et effacé le cache mais je reçois toujours la même erreur. –

+0

Si l'objet Bitmap n'aime pas être mis en cache, essayez à la place de mettre en mémoire cache le MemoryStream - c'est probablement préférable de toute façon. –

+0

C'est mieux. Je l'ai changé pour mettre en mémoire cache le flux de mémoire et enlevé l'instruction using pour le flux mon seul souci maintenant est que les flux sont non disposés. Pensez-vous que le ramasseur de déchets s'occupera de cela ou est-ce qu'un refactor sera nécessaire? –

Questions connexes