-
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
-
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
>
>
>
>
-
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
>
>
>
>
-
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
> >
> >
> >
> >
>
>
-
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
-
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
> > >
> > >
> > >
> > >
> >
> >
>
>
-
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();
}
-
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.
-
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
-
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)
-
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
-
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.
>
>
-
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
>
>
-
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);
}
-
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
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks