Right way to dispose Image/Bitmap and PictureBox

前端 未结 3 1950
慢半拍i
慢半拍i 2020-11-27 18:14

I am trying to develop a Windows Mobile 6 (in WF/C#) application. There is only one form and on the form there is only a PictureBox object. On it I draw all desired controls

相关标签:
3条回答
  • 2020-11-27 18:28

    You can get an Bitmap object from your controller and then assign it to image property of PictureBox. You should also dispose the current image of PictureBox to release the resource.

     var bmp = controller.GetBitmap();
     pictureBox1.Image.Dispose(); // this releases bitmap resources, required
     pictureBox1.Image = bmp;
    
    0 讨论(0)
  • 2020-11-27 18:42

    I don't think there is a real memory leak. The problem is that you don't dispose the old bitmap, it is up to the GC to clean the stuff. But there is no deterministic way to say when this will happen.

    So i think if you're going to loop through a lot of pictures, you'll see some memory increase and at some other point it will fall down or resist at one position.

    I didn't test it, but maybe this will help a little to make it more deterministic:

    public void Draw() {
        Bitmap bmp = new Bitmap(240,320);
        using(var g = Graphics.FromImage(bmp))
        using(var solidBrush = SolidBrush(Color.Black))
        {
            // draw something with Graphics here.
            g.Clear(Color.Black);
            g.DrawImage(Images.CloseIcon, 16, 48);
            g.DrawImage(Images.RefreshIcon, 46, 48);
            g.FillRectangle(solidBrush, 0, 100, 240, 103);
    
            //Backup old image in pictureBox
            var oldImage = pictureBox.Image;
            pictureBox.Image = bmp; 
            //Release resources from old image
            if(oldImage != null)
                ((IDisposable)oldImage).Dispose();            
        }
    }
    

    Update

    And another idea inspired by jack30lena:

    public static Bitmap LoadBitmap(string path)
    {
        //Open file in read only mode
        using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
        //Get a binary reader for the file stream
        using (BinaryReader reader = new BinaryReader(stream))
        {
            //copy the content of the file into a memory stream
            var memoryStream = new MemoryStream(reader.ReadBytes((int)stream.Length));
            //make a new Bitmap object the owner of the MemoryStream
            return new Bitmap(memoryStream);
        }
    }
    

    The idea behind my second code sample is to get rid of the file handle and copy the file content into memory. Afterwards the Bitmap will taken ownership of the MemoryStream which will be disposed within my first sample by calling the oldImage.Dispose().

    By using this approach there should never be more then two images in memory, thous leading only to OutOfMemoryExceptions by really big pictures or small amount of RAM.

    0 讨论(0)
  • 2020-11-27 18:47

    1: I dont know if it works in Windows Mobile but try this:

    FileStream bitmapFile = new FileStream("mybitmap.bmp", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
    Image loaded = new Bitmap(bitmapFile);
    

    2: The SolidBrush must be disposed. There is a general rule for dispose. --> "every object, instanciated by you, that implements dispose must be disposed manually, exept when the object is a return/ref/out value"

    In this case it is better to use a using statement

    using (new objecttodispose){ ..... } 
    

    The using statement will ensure the call of Dispose() in any case (exception for example).

    3: Dispose() will free the bitmap ressources.

    0 讨论(0)
提交回复
热议问题