Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. To Dispose() or not Dispose(), that is the question.

To Dispose() or not Dispose(), that is the question.

Scheduled Pinned Locked Moved C#
graphicshelpquestionworkspace
6 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    Peter Trevor
    wrote on last edited by
    #1

    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();
    

    }

    L 1 Reply Last reply
    0
    • P Peter Trevor

      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();
      

      }

      L Offline
      L Offline
      Luc Pattyn
      wrote on last edited by
      #2

      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


      F 1 Reply Last reply
      0
      • L Luc Pattyn

        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


        F Offline
        F Offline
        fly904
        wrote on last edited by
        #3

        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)

        L 1 Reply Last reply
        0
        • F fly904

          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)

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #4

          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


          F 1 Reply Last reply
          0
          • L Luc Pattyn

            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


            F Offline
            F Offline
            fly904
            wrote on last edited by
            #5

            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)

            L 1 Reply Last reply
            0
            • F fly904

              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)

              L Offline
              L Offline
              Luc Pattyn
              wrote on last edited by
              #6

              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

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups