Dispose Causes Errors


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Page 1 of 2 12 LastLast
Results 1 to 15 of 21

Thread: Dispose Causes Errors

  1. #1
    Jonathan Wood Guest

    Dispose Causes Errors

    This having to clean up objects manually seems even harder than I originally
    thought.

    The following code is in a C# UserControl:

    protected override void OnPaint(PaintEventArgs e)
    {
    SolidBrush brush;

    brush = (SolidBrush)Brushes.Red;
    e.Graphics.DrawString("Hello, world!", Font, brush, e.ClipRectangle);
    // brush.Dispose();
    }

    It seems to work as expected. However, if I uncomment the brush.Dispose()
    line, I get the error "An unhandled exception of type
    'System.ArgumentException' occurred in
    C:\WINDOWS\Microsoft.NET\Framework\v1.0.2204\System.WinForms.DLL" the second
    time it repaints and it breaks to the line after Application.Run() in my
    main form's class.

    ???

    --
    Jonathan Wood
    SoftCircuits Programming
    http://www.softcircuits.com





  2. #2
    Jonathan Allen Guest

    Re: Dispose Causes Errors

    Make a bug report, Dispose should never throw an exception.

    --
    Jonathan Allen


    "Jonathan Wood" <jwood@softcircuits.com> wrote in message
    news:3a7a56bb@news.devx.com...
    > This having to clean up objects manually seems even harder than I

    originally
    > thought.
    >
    > The following code is in a C# UserControl:
    >
    > protected override void OnPaint(PaintEventArgs e)
    > {
    > SolidBrush brush;
    >
    > brush = (SolidBrush)Brushes.Red;
    > e.Graphics.DrawString("Hello, world!", Font, brush, e.ClipRectangle);
    > // brush.Dispose();
    > }
    >
    > It seems to work as expected. However, if I uncomment the brush.Dispose()
    > line, I get the error "An unhandled exception of type
    > 'System.ArgumentException' occurred in
    > C:\WINDOWS\Microsoft.NET\Framework\v1.0.2204\System.WinForms.DLL" the

    second
    > time it repaints and it breaks to the line after Application.Run() in my
    > main form's class.
    >
    > ???
    >
    > --
    > Jonathan Wood
    > SoftCircuits Programming
    > http://www.softcircuits.com
    >
    >
    >
    >




  3. #3
    Jeff Peil Guest

    Re: Dispose Causes Errors

    Jonathan,

    You didn't allocate a Pen, you merely used the existing pen (remember
    "brush" is a reference so you are setting brush to reference the same
    instance that Brushes.Red references)

    If you allocate something you should dispose of it, if someone else is
    managing the lifetime of an object (like the Brushes class) then you should
    not be disposing it.

    "Jonathan Wood" <jwood@softcircuits.com> wrote in message
    news:3a7a56bb@news.devx.com...
    > This having to clean up objects manually seems even harder than I

    originally
    > thought.
    >
    > The following code is in a C# UserControl:
    >
    > protected override void OnPaint(PaintEventArgs e)
    > {
    > SolidBrush brush;
    >
    > brush = (SolidBrush)Brushes.Red;
    > e.Graphics.DrawString("Hello, world!", Font, brush, e.ClipRectangle);
    > // brush.Dispose();
    > }
    >
    > It seems to work as expected. However, if I uncomment the brush.Dispose()
    > line, I get the error "An unhandled exception of type
    > 'System.ArgumentException' occurred in
    > C:\WINDOWS\Microsoft.NET\Framework\v1.0.2204\System.WinForms.DLL" the

    second
    > time it repaints and it breaks to the line after Application.Run() in my
    > main form's class.
    >
    > ???
    >
    > --
    > Jonathan Wood
    > SoftCircuits Programming
    > http://www.softcircuits.com
    >
    >
    >
    >




  4. #4
    Jonathan Allen Guest

    Re: Dispose Causes Errors

    The fact that Brushes.Red is a Readonly property lends credit to you stance.
    But since nether the docs nor the error message say that, so it should still
    be reported as a bug.

    --
    Jonathan Allen


    "Jeff Peil" <jpeil@bigfoot.com> wrote in message
    news:3a7a8c9f@news.devx.com...
    > Jonathan,
    >
    > You didn't allocate a Pen, you merely used the existing pen (remember
    > "brush" is a reference so you are setting brush to reference the same
    > instance that Brushes.Red references)
    >
    > If you allocate something you should dispose of it, if someone else is
    > managing the lifetime of an object (like the Brushes class) then you

    should
    > not be disposing it.
    >
    > "Jonathan Wood" <jwood@softcircuits.com> wrote in message
    > news:3a7a56bb@news.devx.com...
    > > This having to clean up objects manually seems even harder than I

    > originally
    > > thought.
    > >
    > > The following code is in a C# UserControl:
    > >
    > > protected override void OnPaint(PaintEventArgs e)
    > > {
    > > SolidBrush brush;
    > >
    > > brush = (SolidBrush)Brushes.Red;
    > > e.Graphics.DrawString("Hello, world!", Font, brush,

    e.ClipRectangle);
    > > // brush.Dispose();
    > > }
    > >
    > > It seems to work as expected. However, if I uncomment the

    brush.Dispose()
    > > line, I get the error "An unhandled exception of type
    > > 'System.ArgumentException' occurred in
    > > C:\WINDOWS\Microsoft.NET\Framework\v1.0.2204\System.WinForms.DLL" the

    > second
    > > time it repaints and it breaks to the line after Application.Run() in my
    > > main form's class.
    > >
    > > ???
    > >
    > > --
    > > Jonathan Wood
    > > SoftCircuits Programming
    > > http://www.softcircuits.com
    > >
    > >
    > >
    > >

    >
    >




  5. #5
    Jonathan Wood Guest

    Re: Dispose Causes Errors

    Jeff,

    > You didn't allocate a Pen, you merely used the existing pen (remember
    > "brush" is a reference so you are setting brush to reference the same
    > instance that Brushes.Red references)


    I'm not quite following this. First off, if I'm using the default pen, it
    doesn't seem like I should have to worry about that. As far as the brush
    goes, I couldn't figure out how to use new with it. It tells me that the
    SolidBrush contructor is not available due to protection levels. Perhaps a
    tiny code snippet would clarify what you are saying I should do here. (Also,
    I can't say that I know why brush is a reference.)

    Thanks.

    --
    Jonathan Wood
    SoftCircuits Programming
    http://www.softcircuits.com



  6. #6
    Jonathan Wood Guest

    Re: Dispose Causes Errors

    I will clarify where the exception is being thrown from and report a bug.

    --
    Jonathan Wood
    SoftCircuits Programming
    http://www.softcircuits.com
    "Jonathan Allen" <greywolfcs@bigfoot.com> wrote in message
    news:3a7a9551@news.devx.com...
    > The fact that Brushes.Red is a Readonly property lends credit to you

    stance.
    > But since nether the docs nor the error message say that, so it should

    still
    > be reported as a bug.
    >
    > --
    > Jonathan Allen
    >
    >
    > "Jeff Peil" <jpeil@bigfoot.com> wrote in message
    > news:3a7a8c9f@news.devx.com...
    > > Jonathan,
    > >
    > > You didn't allocate a Pen, you merely used the existing pen (remember
    > > "brush" is a reference so you are setting brush to reference the same
    > > instance that Brushes.Red references)
    > >
    > > If you allocate something you should dispose of it, if someone else is
    > > managing the lifetime of an object (like the Brushes class) then you

    > should
    > > not be disposing it.
    > >
    > > "Jonathan Wood" <jwood@softcircuits.com> wrote in message
    > > news:3a7a56bb@news.devx.com...
    > > > This having to clean up objects manually seems even harder than I

    > > originally
    > > > thought.
    > > >
    > > > The following code is in a C# UserControl:
    > > >
    > > > protected override void OnPaint(PaintEventArgs e)
    > > > {
    > > > SolidBrush brush;
    > > >
    > > > brush = (SolidBrush)Brushes.Red;
    > > > e.Graphics.DrawString("Hello, world!", Font, brush,

    > e.ClipRectangle);
    > > > // brush.Dispose();
    > > > }
    > > >
    > > > It seems to work as expected. However, if I uncomment the

    > brush.Dispose()
    > > > line, I get the error "An unhandled exception of type
    > > > 'System.ArgumentException' occurred in
    > > > C:\WINDOWS\Microsoft.NET\Framework\v1.0.2204\System.WinForms.DLL" the

    > > second
    > > > time it repaints and it breaks to the line after Application.Run() in

    my
    > > > main form's class.
    > > >
    > > > ???
    > > >
    > > > --
    > > > Jonathan Wood
    > > > SoftCircuits Programming
    > > > http://www.softcircuits.com
    > > >
    > > >
    > > >
    > > >

    > >
    > >

    >
    >




  7. #7
    Jeff Peil Guest

    Re: Dispose Causes Errors


    "Jonathan Wood" <jwood@softcircuits.com> wrote in message
    news:3a7aece7@news.devx.com...
    >
    > I'm not quite following this. First off, if I'm using the default pen, it
    > doesn't seem like I should have to worry about that. As far as the brush
    > goes, I couldn't figure out how to use new with it. It tells me that the
    > SolidBrush contructor is not available due to protection levels. Perhaps a
    > tiny code snippet would clarify what you are saying I should do here.

    (Also,
    > I can't say that I know why brush is a reference.)
    >


    When you declare a variable, if the type of the variable is a reference
    type(class), you've declared a reference. If the type is a value type
    (struct) you've declared a local instance. Brush is a class, thus when you
    declare a variable to be of type Brush you are declaring a reference.

    Your code rewritten to create a new SolidBrush:

    protected override void OnPaint(PaintEventArgs e)
    {
    SolidBrush brush;

    brush = new SolidBrush(System.Drawing.Color.Red);
    e.Graphics.DrawString("Hello, world!", Font, brush, e.ClipRectangle);
    brush.Dispose();
    }




  8. #8
    Jeff Peil Guest

    Re: Dispose Causes Errors


    "Jonathan Allen" <greywolfcs@bigfoot.com> wrote in message
    news:3a7a9551@news.devx.com...
    > The fact that Brushes.Red is a Readonly property lends credit to you

    stance.
    > But since nether the docs nor the error message say that, so it should

    still
    > be reported as a bug.
    >


    Jonathan,

    What the other Jonathan is doing is disposing of an object, and then trying
    to continue using it, of course that should not work.



  9. #9
    Jonathan Wood Guest

    Re: Dispose Causes Errors

    Jeff,

    > When you declare a variable, if the type of the variable is a reference
    > type(class), you've declared a reference. If the type is a value type
    > (struct) you've declared a local instance. Brush is a class, thus when

    you
    > declare a variable to be of type Brush you are declaring a reference.


    So every assignment to a class creates a reference unless you use new? Makes
    sense I guess (if that's what you're saying).

    > protected override void OnPaint(PaintEventArgs e)
    > {
    > SolidBrush brush;
    >
    > brush = new SolidBrush(System.Drawing.Color.Red);
    > e.Graphics.DrawString("Hello, world!", Font, brush, e.ClipRectangle);
    > brush.Dispose();
    > }


    Dang! I could not do that before. I tried it in the declaration. Oh, I see.
    I wasn't using new there either.

    Looks good. Thanks!

    --
    Jonathan Wood
    SoftCircuits Programming
    http://www.softcircuits.com



  10. #10
    Jeff Peil Guest

    Re: Dispose Causes Errors


    "Jonathan Wood" <jwood@softcircuits.com> wrote in message
    news:3a7b25ca@news.devx.com...
    > So every assignment to a class creates a reference unless you use new?

    Makes
    > sense I guess (if that's what you're saying).


    Well you aren't assigning to a class, you are assigning to a "reference to a
    class" When you declare a variable using a class type, you are declaring a
    reference (which is something like a hybrid between a C++ reference and a
    C++ pointer, in that for all operations *other* than assignment it acts
    similarly to a C++ reference, and for assignment it acts like a C++ pointer,
    in that you are changing what the variable references, and not manipulating
    the referenced object.)

    > Dang! I could not do that before. I tried it in the declaration. Oh, I

    see.
    > I wasn't using new there either.
    >
    > Looks good. Thanks!


    Sure, though I would point out that it makes more sense to use the brushes
    declared in the Brushes class (and *not* disposing them) when possible, as
    you are just wasting cycles to allocate an additional brush and release it
    (that is, when there is an existing brush that has the properties you are
    after.)

    I'd also point out that you really get no benefit in the code you presented
    declaring "brush" as a SolidBrush instead of a Brush (remember unlike C++
    your variable is a reference, not an instance, and so assigning a Brush
    reference to reference a SolidBrush is not a slicing operation)



  11. #11
    Jonathan Wood Guest

    Re: Dispose Causes Errors

    Jeff,

    > Well you aren't assigning to a class, you are assigning to a "reference to

    a
    > class" When you declare a variable using a class type, you are declaring

    a
    > reference (which is something like a hybrid between a C++ reference and a
    > C++ pointer, in that for all operations *other* than assignment it acts
    > similarly to a C++ reference, and for assignment it acts like a C++

    pointer,
    > in that you are changing what the variable references, and not

    manipulating
    > the referenced object.)


    Okay, by assignment I just meant putting on the left of an equal sign. Yeah,
    that makes sense.

    > Sure, though I would point out that it makes more sense to use the brushes
    > declared in the Brushes class (and *not* disposing them) when possible, as
    > you are just wasting cycles to allocate an additional brush and release it
    > (that is, when there is an existing brush that has the properties you are
    > after.)


    This bothers me. Suppose I have an if statement that sets it to different
    things depending on various conditions? It'd be great (and what I'm used to)
    if the thing would just clean up intelligently. Having to know when and how
    to clean up objects is not something I'm used to.

    > I'd also point out that you really get no benefit in the code you

    presented
    > declaring "brush" as a SolidBrush instead of a Brush (remember unlike C++
    > your variable is a reference, not an instance, and so assigning a Brush
    > reference to reference a SolidBrush is not a slicing operation)


    I had trouble doing that too. <g> Don't recall why. I'll try it again.

    Thanks.

    --
    Jonathan Wood
    SoftCircuits Programming
    http://www.softcircuits.com



  12. #12
    Jonathan Allen Guest

    Re: Dispose Causes Errors

    > What the other Jonathan is doing is disposing of an object, and then
    trying
    > to continue using it, of course that should not work.


    I understand. But since the lifetime of the brush is controlled by the
    framework, Dispose should be hidden. Or if it can't be, then it should at
    least be better documented.

    --
    Jonathan Allen


    "Jeff Peil" <jpeil@bigfoot.com> wrote in message
    news:3a7b1def@news.devx.com...
    >
    > "Jonathan Allen" <greywolfcs@bigfoot.com> wrote in message
    > news:3a7a9551@news.devx.com...
    > > The fact that Brushes.Red is a Readonly property lends credit to you

    > stance.
    > > But since nether the docs nor the error message say that, so it should

    > still
    > > be reported as a bug.
    > >

    >
    > Jonathan,
    >
    > What the other Jonathan is doing is disposing of an object, and then

    trying
    > to continue using it, of course that should not work.
    >
    >




  13. #13
    Jonathan Allen Guest

    Re: Dispose Causes Errors

    > Having to know when and how
    > to clean up objects is not something I'm used to.


    We all have to go through that. But unlike C++, the repercussions of messing
    up are not that bad. If you forget, then the GC will handle it eventually.
    If you do it too soon, then you consistently error out.

    In C++, forgetting leads to memory leaks. Doing it too soon can result in
    intermittent logic errors and GPFs, which are heard to detect. The GC is not
    a perfect solution, but it is better than what we had.

    --
    Jonathan Allen


    "Jonathan Wood" <jwood@softcircuits.com> wrote in message
    news:3a7b3c57@news.devx.com...
    > Jeff,
    >
    > > Well you aren't assigning to a class, you are assigning to a "reference

    to
    > a
    > > class" When you declare a variable using a class type, you are

    declaring
    > a
    > > reference (which is something like a hybrid between a C++ reference and

    a
    > > C++ pointer, in that for all operations *other* than assignment it acts
    > > similarly to a C++ reference, and for assignment it acts like a C++

    > pointer,
    > > in that you are changing what the variable references, and not

    > manipulating
    > > the referenced object.)

    >
    > Okay, by assignment I just meant putting on the left of an equal sign.

    Yeah,
    > that makes sense.
    >
    > > Sure, though I would point out that it makes more sense to use the

    brushes
    > > declared in the Brushes class (and *not* disposing them) when possible,

    as
    > > you are just wasting cycles to allocate an additional brush and release

    it
    > > (that is, when there is an existing brush that has the properties you

    are
    > > after.)

    >
    > This bothers me. Suppose I have an if statement that sets it to different
    > things depending on various conditions? It'd be great (and what I'm used

    to)
    > if the thing would just clean up intelligently. Having to know when and

    how
    > to clean up objects is not something I'm used to.
    >
    > > I'd also point out that you really get no benefit in the code you

    > presented
    > > declaring "brush" as a SolidBrush instead of a Brush (remember unlike

    C++
    > > your variable is a reference, not an instance, and so assigning a Brush
    > > reference to reference a SolidBrush is not a slicing operation)

    >
    > I had trouble doing that too. <g> Don't recall why. I'll try it again.
    >
    > Thanks.
    >
    > --
    > Jonathan Wood
    > SoftCircuits Programming
    > http://www.softcircuits.com
    >
    >




  14. #14
    Jeff Peil Guest

    Re: Dispose Causes Errors

    Hi Jonathan,

    "Jonathan Wood" <jwood@softcircuits.com> wrote in message
    news:3a7b3c57@news.devx.com...
    >
    > Okay, by assignment I just meant putting on the left of an equal sign.

    Yeah,
    > that makes sense.


    You might want to take a moment to examine the same code written in ME C++,
    as you really need to get your head around the concept that when you are
    declaring references in C# it is the equivalent of declaring pointers in
    C++. You are not declaring an object on the stack.

    > This bothers me. Suppose I have an if statement that sets it to different
    > things depending on various conditions? It'd be great (and what I'm used

    to)
    > if the thing would just clean up intelligently. Having to know when and

    how
    > to clean up objects is not something I'm used to.


    Well ideally you write things so that still happens. For example, either
    always allocate when making your brush selection, or consider having some
    other place where that is managed place the drawing code in a method that is
    called.

    Something like

    protected override void OnPaint(PaintEventArgs e)
    {
    if(SomeCondition)
    {
    RealPaintFunc(e, Brushes.Red);
    }
    else
    {
    Brush brush = null;
    try
    {
    brush = new SolidBrush(SomeColor);
    RealPaintFunc(e, brush);
    }
    finally
    {
    if(brush!=null) brush.Dispose();
    }
    }
    }

    protected virtual void RealPaintFunc(PaintEventArgs e, Brush brush)
    {
    e.Graphics.DrawString("Hello, world!", Font, brush, e.ClipRectangle);
    }





  15. #15
    Jonathan Wood Guest

    Re: Dispose Causes Errors

    Jonathan,

    > > Having to know when and how
    > > to clean up objects is not something I'm used to.

    >
    > We all have to go through that. But unlike C++, the repercussions of

    messing
    > up are not that bad. If you forget, then the GC will handle it eventually.
    > If you do it too soon, then you consistently error out.


    True. As long as you don't run out of resources used by the class.

    > In C++, forgetting leads to memory leaks. Doing it too soon can result in
    > intermittent logic errors and GPFs, which are heard to detect. The GC is

    not
    > a perfect solution, but it is better than what we had.


    C++ is a manly language! <g>

    Seriously, I really like C++. It's incredibly flexible while still being
    efficient. I probably won't be able to fairly compare the two until I'm
    completely at home with C#.

    --
    Jonathan Wood
    SoftCircuits Programming
    http://www.softcircuits.com



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center