To Dispose() or not Dispose(), that is the question.
-
Okay, I’m confused on what to Dispose and when. Below is a subroutine called from a loop. First time through it is okay, the second time through it throws a System.Exception “Parameter is not valid” on the DrawString line. But if I remove all the Dispose commands at the bottom I can call this subroutine a dozen times without error. Obviously in this instance I can just remove the Dispose commands and move on but I want to understand when I should or shouldn’t call Dispose. (After all I might be missing some Dispose calls elsewhere in my program.)
private void DrawRotatedText(Graphics Canvas, string text, Rectangle DestRect)
{
//Create temp workspace
Bitmap bmp = new Bitmap(500, 500, PixelFormat.Format64bppArgb);
Graphics g = Graphics.FromImage(bmp);
g.Clear(Color.White);//Write on it Font font = new Font("Arial", 12, FontStyle.Regular, GraphicsUnit.Pixel); Brush brush = Brushes.Black; StringFormat stringFormat = new StringFormat(); stringFormat.Alignment = StringAlignment.Center; stringFormat.LineAlignment = StringAlignment.Center; g.DrawString(text, font, brush, (bmp.Width / 2), (bmp.Height / 2), stringFormat); //Rotate image here Bitmap bmp2 = Rotator.RotateImage(bmp, (360 - 45)); // Set the transparency color key based on the upper-left pixel of the image. ImageAttributes attr = new ImageAttributes(); attr.SetColorKey(bmp.GetPixel(0, 0), bmp.GetPixel(0, 0)); // Draw the image using the image attributes. Rectangle SrcRect = new Rectangle((bmp2.Width / 2) - (DestRect.Width / 2), (bmp2.Height / 2) - (DestRect.Height / 2), DestRect.Width, DestRect.Height); Canvas.DrawImage(bmp2, DestRect, SrcRect.Left, SrcRect.Top, SrcRect.Width, SrcRect.Height, GraphicsUnit.Pixel, attr); //Tidy up bmp.Dispose(); font.Dispose(); brush.Dispose(); stringFormat.Dispose(); bmp2.Dispose(); attr.Dispose(); g.Dispose();
}
-
Okay, I’m confused on what to Dispose and when. Below is a subroutine called from a loop. First time through it is okay, the second time through it throws a System.Exception “Parameter is not valid” on the DrawString line. But if I remove all the Dispose commands at the bottom I can call this subroutine a dozen times without error. Obviously in this instance I can just remove the Dispose commands and move on but I want to understand when I should or shouldn’t call Dispose. (After all I might be missing some Dispose calls elsewhere in my program.)
private void DrawRotatedText(Graphics Canvas, string text, Rectangle DestRect)
{
//Create temp workspace
Bitmap bmp = new Bitmap(500, 500, PixelFormat.Format64bppArgb);
Graphics g = Graphics.FromImage(bmp);
g.Clear(Color.White);//Write on it Font font = new Font("Arial", 12, FontStyle.Regular, GraphicsUnit.Pixel); Brush brush = Brushes.Black; StringFormat stringFormat = new StringFormat(); stringFormat.Alignment = StringAlignment.Center; stringFormat.LineAlignment = StringAlignment.Center; g.DrawString(text, font, brush, (bmp.Width / 2), (bmp.Height / 2), stringFormat); //Rotate image here Bitmap bmp2 = Rotator.RotateImage(bmp, (360 - 45)); // Set the transparency color key based on the upper-left pixel of the image. ImageAttributes attr = new ImageAttributes(); attr.SetColorKey(bmp.GetPixel(0, 0), bmp.GetPixel(0, 0)); // Draw the image using the image attributes. Rectangle SrcRect = new Rectangle((bmp2.Width / 2) - (DestRect.Width / 2), (bmp2.Height / 2) - (DestRect.Height / 2), DestRect.Width, DestRect.Height); Canvas.DrawImage(bmp2, DestRect, SrcRect.Left, SrcRect.Top, SrcRect.Width, SrcRect.Height, GraphicsUnit.Pixel, attr); //Tidy up bmp.Dispose(); font.Dispose(); brush.Dispose(); stringFormat.Dispose(); bmp2.Dispose(); attr.Dispose(); g.Dispose();
}
Hi, it is good practice to Dispose of objects that satisfy all these conditions: 1. they have a public Dispose() method 2. you don't need them anymore 3. you did cause their creation. This includes all "new Somethings()", all "CreateXxx()" results, and some specials such as Image.FromFile(); it excludes the objects you are borrowing, such as the Graphics you get from PaintEventArgs, the Brush you get from Brushes.Black, etc. There also is no need to Dispose of Controls that reside on a Form: when the Form gets closed, the Controls get Disposed of automatically. there are two good reasons to call Dispose explicitly: 1. the object may contain unmanaged resources (e.g. memory blocks allocated outside the CLR) 2. the object may be expensive (e.g. use lots of memory) Disposing it explicitly does whatever is necessary to free the resources (when unmanaged) or make them collectable (when managed). it is also common practice to Dispose in reverse order, hence a=new A(), b=new B(), b.Dispose(), a.Dispose(); this may be relevant when b actually depends on a as in b=new B(a); it may be wise to include null tests, as in
if (b!=null) b.Dispose();
in case you are not sure b really got created (say in a finally block where the try part maybe didn't complete). :)Luc Pattyn [Forum Guidelines] [My Articles]
Avoiding unwanted divs (as in "articles needing approval") with the help of this FireFox add-in
-
Hi, it is good practice to Dispose of objects that satisfy all these conditions: 1. they have a public Dispose() method 2. you don't need them anymore 3. you did cause their creation. This includes all "new Somethings()", all "CreateXxx()" results, and some specials such as Image.FromFile(); it excludes the objects you are borrowing, such as the Graphics you get from PaintEventArgs, the Brush you get from Brushes.Black, etc. There also is no need to Dispose of Controls that reside on a Form: when the Form gets closed, the Controls get Disposed of automatically. there are two good reasons to call Dispose explicitly: 1. the object may contain unmanaged resources (e.g. memory blocks allocated outside the CLR) 2. the object may be expensive (e.g. use lots of memory) Disposing it explicitly does whatever is necessary to free the resources (when unmanaged) or make them collectable (when managed). it is also common practice to Dispose in reverse order, hence a=new A(), b=new B(), b.Dispose(), a.Dispose(); this may be relevant when b actually depends on a as in b=new B(a); it may be wise to include null tests, as in
if (b!=null) b.Dispose();
in case you are not sure b really got created (say in a finally block where the try part maybe didn't complete). :)Luc Pattyn [Forum Guidelines] [My Articles]
Avoiding unwanted divs (as in "articles needing approval") with the help of this FireFox add-in
Luc Pattyn wrote:
it is good practice to Dispose of objects that satisfy all these conditions: 1. they have a public Dispose() method
What if it didn't? Would setting it to null do/be the same? Would setting it to null enable the garbage collector to execute the destructor(if defined) quicker? eg:
ExampleClass ex = new ExampleClass();
ex.DoSomething();
ex = null;My failometer is detecting vast quantities of FAIL! "Its SQL - hardly programming..." (Caslen)
-
Luc Pattyn wrote:
it is good practice to Dispose of objects that satisfy all these conditions: 1. they have a public Dispose() method
What if it didn't? Would setting it to null do/be the same? Would setting it to null enable the garbage collector to execute the destructor(if defined) quicker? eg:
ExampleClass ex = new ExampleClass();
ex.DoSomething();
ex = null;My failometer is detecting vast quantities of FAIL! "Its SQL - hardly programming..." (Caslen)
fly904 wrote:
Would setting it to null do/be the same?
setting a reference to null removes one reference to some object. If that happened to be the last live reference, the object becomes collectable, which does not free any memory yet, since the GC has to run first to discover that. And it does not close a file, does not free other managed resources, and does not free any unmanaged resources, say memory that got malloced in native code, will not get freed ever if there is no Dispose(); BTW: Windows will clean up everything when the process exits. If a Dispose exists but is not called by your code, it will get called by the GC when the object gets finalized, which may be much later. Do you want to keep the large memory footprint longer than necessary, do you want to keep files open longer then necessary, ...? I don't think so. :)
Luc Pattyn [Forum Guidelines] [My Articles]
Avoiding unwanted divs (as in "articles needing approval") with the help of this FireFox add-in
-
fly904 wrote:
Would setting it to null do/be the same?
setting a reference to null removes one reference to some object. If that happened to be the last live reference, the object becomes collectable, which does not free any memory yet, since the GC has to run first to discover that. And it does not close a file, does not free other managed resources, and does not free any unmanaged resources, say memory that got malloced in native code, will not get freed ever if there is no Dispose(); BTW: Windows will clean up everything when the process exits. If a Dispose exists but is not called by your code, it will get called by the GC when the object gets finalized, which may be much later. Do you want to keep the large memory footprint longer than necessary, do you want to keep files open longer then necessary, ...? I don't think so. :)
Luc Pattyn [Forum Guidelines] [My Articles]
Avoiding unwanted divs (as in "articles needing approval") with the help of this FireFox add-in
I want to be in charge of the Garbage Collector... I see it go past my window every thursday morning and I think to myself, if only I could control that contraption, then I could control those little minions which serve it... then I shall rule the world. But I normally just go back to sleep. ps. Thanks, you cleared alot of my questions up. :thumbsup:
My failometer is detecting vast quantities of FAIL! "Its SQL - hardly programming..." (Caslen)
-
I want to be in charge of the Garbage Collector... I see it go past my window every thursday morning and I think to myself, if only I could control that contraption, then I could control those little minions which serve it... then I shall rule the world. But I normally just go back to sleep. ps. Thanks, you cleared alot of my questions up. :thumbsup:
My failometer is detecting vast quantities of FAIL! "Its SQL - hardly programming..." (Caslen)
You're welcome. FYI: setting a reference to null generates a particular IL instruction (not just a store null), which strictly speaking could be skipped as the variable isn't going to be used anymore. The special instruction basically tells the JIT compiler it should generate code that clears the reference and it should NOT optimize the instruction away! :)
Luc Pattyn [Forum Guidelines] [My Articles]
Avoiding unwanted divs (as in "articles needing approval") with the help of this FireFox add-in
modified on Tuesday, May 5, 2009 10:09 PM