glautrou
glautrou

Reputation: 3198

Dispose() - What call this and when

I have this piece of code:

using (var img = Bitmap.FromFile(path))
{
    result = new Bitmap(img);
}

Questions:

  1. Is the Bitmap instance immediately called at the end of the using? or is it waiting to be garbage collected?
  2. Is it disposed from the current thread or another?

Upvotes: 2

Views: 200

Answers (4)

Bassam Alugili
Bassam Alugili

Reputation: 17033

using is a syntactic sugar for the try/finally pattern, after the brackets is closed the Img.Dispose(); will be in behind called.

using (var img = Bitmap.FromFile(path))
{
   result = new Bitmap(img);
}  // here Dispose will be immediately called.

if you are using img/result here you will get an Exception.

Threads have nothing to do with this matter! Dispose called always in the current thread.

Upvotes: 0

Hans Passant
Hans Passant

Reputation: 942237

It is neither garbage collected nor disposed. You write code like this to create a deep copy of a bitmap. Different from Bitmap.Clone() which creates a shallow copy. You use it to avoid taking a lock on the path file. Such locks can be very troublesome later when you try to save the image back, that fails with a GenericException.

The Bitmap(Image) constructor creates the copy by using Graphics.DrawImage(). The using statement on the img variable releases the lock on the file.

This is not entirely without trouble btw, a deep copy costs a lot of memory and can significantly increase the commit size of your process when the image is large. Or in other words, it is expensive and you'll run the risk of your program bombing with OutOfMemoryException. There's also a flaw, the Bitmap(Image) constructor forgets to copy the Image.HorizontalResolution and VerticalResolution properties. So the image might not be displayed at the same size.

Upvotes: 1

Dave Zych
Dave Zych

Reputation: 21897

Your code is equivalent to the following (which is actually how the code is translated by the compiler):

try
{
    var img = Bitmap.FromFile(path);
    result = new Bitmap(img);
}
finally
{
    img.Dispose();
}

Note that result never had Dispose called on it, and it is up to the calling code to properly dispose of the object.

Upvotes: 2

D Stanley
D Stanley

Reputation: 152624

You actually have two Bitmap instances - img and result.

img will get disposed (I believe on the current thread) at the end of the using block. The compiler inserts a Dispose call in a finally block for you.

result does NOT get disposed automatically - whatever consumes result will need to dispose of it.

Also note that getting disposed and garbage collected are two different things - Dispose will clean up any unmanaged resources immediately (in the case of a Bitmap it will be the underlying graphics objects), but any managed resources will be garbage collected as some later, undetermined time.

Upvotes: 3

Related Questions