Does Pen.Dispose dispose of the underlying brush? - c#

I create a new Pen Object:
Private NewPen As New Pen(New SolidBrush(Color.FromArgb(12,52,220)))
When I now call NewPen.Dispose does it also dispose of the SolidBrush I used to create the pen, or do I have to dispose of it separately?

No. The Private keyword in your snippet is the only real hint that you are making a mistake. That implies that you made the pen a field of a class. That's never the correct thing to do, drawing objects are very cheap to create (about a microsecond) but expensive to keep around. They get allocated on a desktop heap that all programs that run on that desktop need to share. You never want to occupy space in that heap needlessly.
Always create a drawing object at the moment you need it. Which lets you fall in the pit of success with the Using statement:
Protected Overrides Sub OnPaint(e As PaintEventArgs)
Using sbr = New SolidBrush(Color.FromArgb(12, 52, 220))
Using pen = New Pen(sbr)
'' Use the pen
''....
End Using
End Using
End Sub
This tends to be pretty unintuitive to many programmers, they usually learn that keeping objects around and re-using them is a Good Thing. The general rule you'd want to keep in mind is that it is usually the reverse for disposable objects. There are some types of objects that are expensive to create so seem to warrant keeping them around. The .NET Framework however always makes an effort to cache them itself. The Font class is a good example.

Simple answer: no. The Pen class (click to view the .net source code) doesn't store any references to the brush. You are responsible for disposing the brush. That's why this returns False:
Using b As New SolidBrush(Color.Black)
Using p As New Pen(b)
Debug.WriteLine("Is equal: {0}", (b Is p.Brush))
End Using
End Using

Related

Image Resource Memory

Since I had a really nasty problem with an not too obvious unmanaged resource last month, I got a little hypernervous regarding memory leaking problems.
I was just coding on a very simple test app with a button with two different pictures on it and noticed I am not quite sure if I have a "problem" here or not...
If I have 2 picture resources Pic1 and Pic2 and an ImageButton-Object, which is just some object inherited from UserControl and with a changed OnPaint:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
//stuff
if (this.keyStatus))
{ this.imageButton.DefaultImage = Resource1.Pic1; }
else
{ this.imageButton.DefaultImage = Resource1.Pic2; }
e.Graphics.DrawImage(this.defaultImage, this.ClientRectangle);
}
Beside OnPaint not being a good place for assigning DefaultImage (its just here to show you what I mean in a short piece of code), I am just assinging a reference to my precompiled resource here, am I? I am not creating a copy as I would if I would call it with new Bitmap(Resource1.Pic1).
So if I change keyStatus every 5 seconds, I would have a very annoying picture on my screen with a lot of changing, but no problems that the picture changing or turning it invisible from time to time leaks memory. Correct?
Thanks a lot!
How object references work
Say you have a random object. The object is a class type (not a value type) and not IDisposable. Basically that means the following:
// y is some object
var x = y;
Now, x doesn't copy all the data from y, but simply makes a new reference to the contents of y. Simple.
To ensure that there won't be memory leaks, the GC keeps track of all objects and (periodically) checks which objects are reachable. If an object is still reachable, it won't be deleted - if it's not, it will be removed.
And then there was unmanaged code
As long as you stick to managed code, everything is fine. The moment you run into unmanaged code (say: GDI+, which is the native counterpart of a lot of System.Drawing stuff) you need to do extra book-keeping to get rid of the code. After all, the .NET runtime doesn't know much about the unmanaged data - it merely knows that there is a pointer. Therefore, the GC will cleanup the pointer, but not the data -- which would result in memory leaks.
Therefore, the guys from .NET added IDisposable. By implementing IDisposable, you can implement extra (unmanaged) cleanup, such as releasing unmanaged memory, closing files, closing sockets, etc.
Now, the GC knows about finalizers, which are implemented as part of the Disposable pattern (details: https://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.110).aspx ). However, you usually don't want to wait for a GC run to clean up unmanaged resources. So, it's generally a good idea to call Dispose() when an object can be cleaned up and has unmanaged resources.
As is the case with System.Drawing.Bitmap, which implements IDisposable.
In most cases, you can simply wrap IDisposable in a using statement, which will call 'Dispose()' for you in a nice try/finally clause. e.g.:
using (var myBitmap = new Bitmap(...))
{
// use myBitmap
}
// myBitmap including all resources are gone.
What about resource bitmaps
#HansPassant pointed out that resource bitmaps generate a new Bitmap every time you access a bitmap property. This basically means that the bitmaps are copied and need to be disposed.
In other words:
// Free the old bitmap if it exists:
if (this.imageButton.DefaultImage != null)
{
this.imageButton.DefaultImage.Dispose();
this.imageButton.DefaultImage = null;
}
// assign new imageButton.DefaultImage
So, this solves the memory leak, but will give you a lot of data that is copied around.
If you don't want to dispose
Here comes the part why I was surprised by the remark from Hans :) Basically you assign a Bitmap to a button every time, so you don't want to copy the data over and over again - that makes little sense.
Therefore, you might get the idea to wrap the resource into a 'static' container and simply don't deallocate it at all:
static Bitmap myPic1 = Resource1.Pic1;
static Bitmap myPic2 = Resource1.Pic2;
...
if (this.keyStatus))
{
this.imageButton.DefaultImage = myPic1;
}
else
{
this.imageButton.DefaultImage = myPic2;
}
This works, but will give you issues if you at some point decide to generate images as well. To illustrate, say we change the code like this::
if (this.keyStatus))
{
this.imageButton.DefaultImage = myPic1; // #1 don't dispose
}
else
{
Bitmap myPic3 = CreateFancyBitmap(); // #2 do dispose
this.imageButton.DefaultImage = myPic3;
}
Now, the issue here is with the combination. myPic1 is a static object and shouldn't be disposed. On the other hand, myPic3 is not, and should be disposed. If you do call Dispose(), you'll get a nasty exception at #1, because the data is no longer there. There's no proper way to distinguish the two.

Generate and Dispose before using?

Today my intstructor, where I'm intern, said I should use
HImage hi = null;
HOperatorSet.GenEmptyObject(out hi);
hi.Dispose();
hi = f.GrabImageAsync(-1.0);
Instead of
HImage hi = null;
hi = f.GrabImageAsync(-1.0);
Prototypes of used functions as follows
void HOperatorSet.GenEmptyObj(out HObject emptyObject);
HImage HFramegrabber.GrabImageAsync(double maxDelay);
I respect my instructor ,but I don't see any meaningful explanation at creating and disposing an object before calling hi = f.GrabImageAsync(-1.0); as that functions returns an instance of that object and therefore no need for Generating and Disposing object first, at least in my opinion.
So anyone can clarify if it is really needed or not. Thank you in advance.
I agree with you. Generally there is no use in creating and immediately disposing a variable.
As far as we can see from the code, HOperatorSet.GenEmptyObject doesn't interact with your f variable, so there would be no meaning in calling that method.
Also, there is no point in setting HImage hi to null, since that is probably the default already and it is set using the out parameter.
So my bet would be on:
HImage hi = f.GrabImageAsync(-1.0);
Most of the time Dispose() is called to release all managed resources that no longer in need. So let's assume that HOperatorSet.GenEmptyObject(out hi) method opens FileStream and saves reference to some field in new HImage instance. Later in code you would like to do other operation with this HImage instance and no longer need this FileStream or any other resources. It's a good moment to call hi.Dispose() that closes it before you proceed with doing anything else. But in any other case your instructor is misleading you.
There are a few classes in WinForms which have multiple purposes, some of which require resources and some of which don't. The one I'm most familiar with is Font. A Font instance encapsulates a combination of font settings as well as a GDI handle to a GDI font resource. The Font property setter of most WinForms controls will cause the controls to copy of the settings from the passed-in font object and store a copy of the passed in Font reference so that it may be returned by a call to the property getter, but will not cause the controls to actually use the passed-in font for drawing. Since the settings can be read from a Font object even after is is disposed, it is in fact possible to create and dispose Font objects when setting controls' Font properties; in some cases it may arguably be a reasonable least-of-evils approach:
If Font objects are created and abandoned without disposal, that will usually not cause too much of a GDI resource drain, but such wishful thinking doesn't represent good design.
A policy of calling Dispose on a control's old value of Font before setting a new value will require that every control own its own separate Font object, which will then encapsulate a resource the control will never use. The one advantage is that code which reads a control's Font property will be able to draw using that Font object directly.
Having controls hold references to font objects that are already disposed will make it possible for multiple controls to safely share the same font object, and will consume fewer GDI resources than either of the other approaches. The one limitation is that any code which reads a control's Font property and wants to draw with that font will have to use it to construct a new Font object for the purpose (and probably dispose of it after use).
IMHO, the fact that disposing Font objects immediately on creation is a useful pattern suggests that the Framework should have included separate types for the purposes of describing fonts (the purpose of a control's Font property) and encapsulating GDI font objects (the purpose of the Font parameter to string-drawing methods). If the latter type had included Dispose and the former type not, there would have been no question about how to use each. Since the Font type exists, however, along with code that uses it for those disjoint purposes, the eager-dispose pattern may be a reasonable least-of-evils approach.
I'm not sure that approach represents what's going on in your instructor's example since I'm not familiar with the types involved. It may be that the object returned by GenEmptyObject doesn't actually allocate any resources and its Dispose method does nothing (and stating that the particular object may be safely abandoned may be better than calling Dispose prematurely) but if the object acquires resources which won't be needed for its intended use, early disposal might possibly be appropriate if commented.

Small objects: create frequently or reuse?

For example, in draw method I need an instance of Rectangle to be used. Like this:
Rectangle rect = new Rectangle(FrameSize * CurrentFrame, 0, FrameSize, FrameSize);
Or other way. Define temp rectangle data member, and then use it like this:
rect.X = FrameSize * CurrentFrame;
rect.Y = 0;
rect.Width = FrameSize;
rect.Height = FrameSize;
Which way is better? One thing confuses me is that many rectangles created frequently, but many code solutions use first approach, while second one should be careful about memory consumptions.
Unless you have proved by careful measurement that reuse improves your performance you should create a new object every time.
.NET handles object creation and GC very efficient, you should not worry about any performance hit here. The second solution needs more careful coding to make sure you don't reuse objects in use somewhere else and you don't have previous state lugging around. Further more you will have more objects aging into gen1 or gen2 in the GC.
I would personally use the first approach in most cases - ideally making the type immutable if it makes sense and if the type is under your control.
The garbage collector is very good at reclaiming short-lived objects - and creating new objects means you don't need to worry about whether something still has a reference to the old object (thus making changes to it a problem).
How long lived are the objects? If they're only created locally and then used by the drawing methods, then chances are they will get collected in generation zero which is fairly efficient.
The problem with re-using a temp rectangle is that if you try to let it hang around beyond the life of a method it will be problematic for modifications in general.
As a general rule, I'd go with #1, and ONLY consider #2 if you discover later after profiling that #1 became an issue.
The former is safer when it comes to possible bugs, in respect to Rectangle class being mutable can produce some weird and hard to spot effects.
I don't think the performance penalty is serious enough to risk venturing in the wild world of mutable structs.
Consider the fact that structs are allocated on stack, in case of drawing method I personally would choose the first approach, as
Object created and initialized
Used
Pushed to GC as we leave the function.
So this is small object which is fast created and fast removed from the memory.
I would do it on an instance basis. You're not gaining much by reusing it, and it makes your code easier to break. By doing it on an instance basis, you can encapsulate some logic in a method and you won't have to worry about it breaking due to factors outside of the method.

Do I need to use using pattern for Font, Brush etc

When programming with GDI+, do I need to stick to using pattern to all kinds of objects like Brush, Font, it can make code very cluttered.
Any suggestions?
Yes, you should do that for all (IDisposable) objects that you create.
The exceptions are the stock objects (Brushes.Blue, Pens.Black, e.Graphics, ...) because you don't create them.
it can make code very cluttered.
using is not as cluttered as a full try/finally. Note that you can economize the nesting:
using (Pen p = ...)
using (Brush b = ...)
{
// draw with p and b
}
But if the choice is between cluttered code or the possibility of the program failing, is there really a choice?
Yes, you should. These objects could contain unmanaged resources (e.g., GDI+ handles) that need to be disposed of properly. So, either use a using block or wrap everything thing in a try / finally statement where in the finally block you invoke IDisposable.Dipose.
Please see these previous answers on this topic:
What Happens if I Don't Call Dispose
Wrapping MemoryStream in a using
If you created the brush using new you should dispose of it.
If you got the brush from the Brushes collection, do not dispose of it. See the remarks section of http://msdn.microsoft.com/en-us/library/system.drawing.brushes.aspx for more info.
The same holds true of fonts, if you created it with new, dispose of it. If you got it from something else, look at the documentation to see if you should dispose if it or not.
Yes, you have to.
Alternative is using default brushes and fonts such as Brushes.Black, ...

How to clone a Graphics in C#?

I want to provide different parts of an application with independent Graphics instances which end up painting on the same base Graphics. Simply cloning the Graphics works, but since both instances refer to the same GDI handle, there are not independent. I can't use Begin and EndContainer as well since I have a method which has to provide the new Graphics instances. -so I cannot determine when to call EndContainer. The use case is quite similar to the Graphics.create() method in Java.
I've found some workarounds, but none of them works for a Graphics provided by the PrintController.
Is there any proxy-Graphics I can use? Or is there a possibility to create another Graphics for the same device for instance?
This sounds bad. Do not store references to a Graphics object, it only ever lives temporarily and is only valid while a Paint or PrintPage event handler is running. Do make sure to pass it as an argument to whatever method does the drawing instead of storing it in a field or a global variable.
If the method is altering the state of the object then use the Save() and Restore() methods to prevent this from causing problems in subsequent methods that use that same object. Cloning it is never necessary with this approach.
Graphics objects are not meant to be persisted. You could use a backbuffer approach by drawing to a Bitmap before your final render.
Perhaps you could raise an event to which listening drawing components could subscribe, and your calling code could chain these together. That way you could use the same Graphics instance without compromising GDI efficiency.
Not sure what exactly you're trying to do but you can use CreateGraphics() on a Control or Graphics.FromImage(xx) to create a new Graphics object for the control and/or image. There's also a few more functions in Graphics.FromXXX
A possibility would be to create multiple graphics objects which are pointing to multiple targets, for example an memory image. Then after done, combine all images into one.
But the thing I don't understand is, if all graphics instances should paint to the same target why do you need multiple graphics objects in the first place?
I was facing same problem, I found the only solution is to duplicate the drawings code line !!
Like the following:
e.Graphics.DrawString(points(i).pointText, myFont, Brushes.Blue, New Point(points(i).crossPointX4, points(i).crossPointY4)) : G.DrawString(points(i).pointText, myFont, Brushes.Blue, New Point(points(i).crossPointX4, points(i).crossPointY4))

Categories