2010-12-08 58 views
1

Mes codes:Deal (Dispose) avec Bitmap et Steam lors du téléchargement et de redimensionner l'image au serveur VB.net

Public Function HandleImageUpload(ByVal serverPath As String, ByVal iWidth As Integer, ByVal iHeight As Integer) As String 


      Dim fileStream As Stream = imageUploader1.PostedFile.InputStream 
      Dim fileName As String 
      Dim newSize As Size = New Size 
      Dim extension As String 
      Dim imageBytes As Byte() 
      Dim stream As New FileStream(serverPath, FileMode.Create) 

      If imageUploader1.HasFile Then 

       If imageUploader1.FileBytes.Length < 4194304 Then 

        imageBytes = imageUploader1.FileBytes 
        fileName = imageUploader1.FileName 
        extension = Path.GetExtension(fileName) 

        If extension.ToLower = ".png" Or extension.ToLower = ".bmp" _ 
         Or extension.ToLower = ".gif" Or extension.ToLower = ".jpg" Then 

         newSize.Width = iWidth 
         newSize.Height = iHeight 

         imageBytes = ResizeImageFile(fileStream, newSize) 

         stream.Write(imageBytes, 0, imageBytes.Length) 
         'need dispose or hte server will keep it' 
         stream.Dispose() 

        End If 
       End If 
      End If 
    End Function 



    Public Function ResizeImageFile(ByVal fileStream As Stream, ByVal newSize As Size) As Byte() 
     Dim memoryStream As MemoryStream = New MemoryStream 

     Dim oldImage As System.Drawing.Image = System.Drawing.Image.FromStream(fileStream) 


     Dim newImage As Bitmap = New Bitmap(newSize.Width, newSize.Height, PixelFormat.Format24bppRgb) 

     Dim canvas As Graphics = Graphics.FromImage(newImage) 
     canvas.SmoothingMode = SmoothingMode.AntiAlias 
     canvas.InterpolationMode = InterpolationMode.HighQualityBicubic 
     canvas.PixelOffsetMode = PixelOffsetMode.HighQuality 

     canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize)) 

     'question here' 
     newImage.Save(memoryStream, ImageFormat.Jpeg) 

     'Dispose right?' 
     oldImage.Dispose() 
     canvas.Dispose() 
     newImage.Dispose() 

     Return memoryStream.GetBuffer 
    End Function 


End Class 
  1. Après que je produis Bitmap newImage, pourrais-je l'enregistrer directement sur le serveur plutôt que l'enregistrer dans memoryStream
  2. De quelle ressource devrais-je disposer? En ce qui concerne MSDN iDisposable modèle, nous avons besoin de disposer de ressources non gérées. How to dispose managed resource in Dispose() method in C#?. Dois-je impliquer finalizer dans ce cas? est-ce que je fais bien?

  3. Les codes peuvent-ils être améliorés? par exemple. écrire au serveur, redimensionner la méthode, etc.

Cordialement,

Répondre

0

1) Oui, vous pouvez et peut-être devriez-vous le faire. MemoryStream est une zone de mémoire transitoire qui doit être fermée.

2) Tout ce qui implémente IDisposable. Vous n'appelez pas finaliseur, GC le fait.

3) Je signalerai et mise à jour sur ce

MISE À JOUR

OK, j'ai regardé et je pense que vous devez faire l'économie dans la méthode ResizeImageFile afin que vous créez le FileStream à l'aide serverPath à l'intérieur HandleImageUpload et passez-le à la méthode ResizeImageFile et lorsque vous enregistrez l'image, au lieu de MemoryStream, vous enregistrez au FileSTream.

Vous faites Return memoryStream.GetBuffer et j'ai déjà testé et je sais que cela ne créera pas de fuite de mémoire alors que vous ne disposez pas réellement du MemoryStream mais il est préférable de le faire explicitement. Bien que la nouvelle solution n'implique pas de flux de mémoire.

+0

merci beaucoup hâte il –

+0

Je décide de générer FileSteam dans 'ResizeImage'. Bravo –

+0

Bon! Alors, mon conseil m'a-t-il aidé? Nous qui demandons la responsabilité de marquer les réponses correctes en tant que telles et de leur donner des points si nous pensons qu'elles étaient utiles. – Aliostad

2

Tout ce qui a Débarrassez-vous voulez appeler Dispose lorsque vous avez terminé. Idéalement, vous devriez encapsuler ces objets dans les instructions using. L'instruction using appelle Dispose pour vous lorsque l'objet est hors de portée.

http://msdn.microsoft.com/en-us/library/htd05whh.aspx

regarder brièvement le code, le problème que vous avez est que si partout dans vos méthodes une exception est levée, les objets ne seront pas avoir la méthode Disposé appelée. Vous devriez au moins enrouler votre code dans un bloc try/catch/finally et mettre la méthode de disposition dans le bloc finally (l'instruction using est une meilleure approche).

Les finaliseurs sont utilisés dans vos objets pour s'assurer que lorsqu'ils sont détruits, rien n'est accidentellement laissé ouvert (comme un fichier). Si tout ce que vous faites est de créer des objets dans les méthodes (pas de variables de niveau classe dont vous devez vous débarrasser), alors vous n'avez pas besoin d'implémenter un Finalizer. Vous ne voulez jamais implémenter un Finalizer personnalisé, sauf si vous en avez besoin, car cela oblige le GC à faire un travail supplémentaire (promeut l'objet au niveau suivant du GC et ne le détruit pas immédiatement). Selon ce que vous avez posté, il semble que vous n'en ayez pas besoin.

+0

super et clair. –

+0

sry, oubliez de mentionner que j'ai enlevé la forme de manipulation d'erreur ce code, semble si j'utilise 'using' alors je n'ai pas besoin de disposer de la ressource. –