views:

68

answers:

5

I have an application that does a lot of drawing, let's pretend it's a Viso-like application. It has objects that have multiple sub-objects that are drawn, things can be connected, resized etc. Currently when I call paint on a particular sub-object or object, I do the following:

using(var pen = new Pen(this.ForeColor))
{
    // Paint for this object.
}

I've read conflicting answers that this should be done for an application that is constantly drawing the same thing (maybe just resized, moved etc). Should I store the Pen/Brush with the object and then dispose them all when the application is disposed of, or are they efficient enough to be created/disposed for each paint call (remembering that this is a pretty graphics intense application).

EDIT: There are already two answers that have conflicting answers and this is where I'm not sure to make the switch. Does anyone have any stats on the differences?

A: 

It doesn't seem like a ton of work to test it out. Everyone's code is different.

Fantius
A: 

Reusing the same Pen and Brush in operations that will require it many times over is going to be a lot faster than disposing of them each time with using.

I would say for sure that it's a good idea to reuse these as much as possible (and I've seen code comparisons before, but I can't source them right now) but do remember to dispose of them when you are truly finished with them.

Codesleuth
@Codesleuth - You wouldn't have any evidence as to *how* much faster? I don't want to do optimization when it's not *really* necessary.
TheCloudlessSky
A: 

Yeah best to test like @fantius suggests, you'll probably find it doesn't really matter - although I'd be temped to keep them open as if I recall correctly they're unmanaged resources and could use up your memory. If you were recreating them every time, you'd need to be especially careful of disposing them properly to avoid memory leaks.

Grant Crofton
@Grant - When recreating them every time, they're disposed with the `using` statement.
TheCloudlessSky
+3  A: 
Andy
@Andy - Yeah all the pens/brushes have different colors than the pre-defined colors.
TheCloudlessSky
OK, fair enough. Please see the edit to my post.
Andy
@Andy - I just did some testing before checking your post and you're right, it's insanely fast to create/dispose. Optimization is unnecessary in this case. Thanks!
TheCloudlessSky
+1  A: 

You'll only know the performance impact by testing on your particular application, but the framework doesn't seem to have a problem keeping a few pens around for the life of the application. The first time you call Pens.Black, it creates a black pen and caches it. You get the same object back for future calls, and it's never explicitly disposed (Pens.Black.Dispose() will actually throw an exception). However, you don't want to blindly create pens and leave them to be disposed when the application ends, because you'll be leaking unmanaged memory. A couple of options spring to mind depending on the pattern of usage in your app.

Give each object a private Pen that's created when ForeColor is set and reused for all painting. You should make your object IDisposable so that it can dispose of that Pen properly.

If you're using relatively few distinct colours but lots of objects use each colour, you may not want each object to hold on to its own Pen. Create some cache class that keeps a Dictionary<Color,Pen> and hands them out through a PenCache.GetPen(ForeColor). Like using Pens.Black, you can now forget about disposing them. A problem arises if you use a colour briefly, then don't need it again. The Pen got cached, so you're stuck with it in memory forever. You could keep a Dictionary<Color,WeakReference<Pen>> instead, allowing cached pens to be eventually garbage collected if they're no longer needed.

That last option may be the best general purpose solution, avoiding gratuitous creation and disposal while letting the garbage collector make sure that orphaned pens don't cause too much memory trouble. It may, of course, not be any better in your particular case.

stevemegson
@steve - +1 since I really like the idea of using `WeafReference`. I'm going to have to read more about it for another project. I've found through some testing that creating/disposing Pens/Brushes is fairly efficient, so I've accepted Andy's answer.
TheCloudlessSky