This post originated from an RSS feed registered with .NET Buzz
by Steve Hebert.
Original Post: question: managing disposable objects in a graphical app
Feed Title: Steve Hebert's Development Blog
Feed URL: /error.htm?aspxerrorpath=/blogs/steve.hebert/rss.aspx
Feed Description: .Steve's .Blog - Including .Net, SQL Server, .Math and everything in between
Whenever I deal with disposable objects, I always wrap them in a using() statement religiously.
Now that I am writing a graphical application where the drawing engine may paint on different surfaces (24-bit bitmap vs. black and white), I've abstracted a 'Pallet' object with concrete implementations for each Pallet type. This allows me to abstractly ask the Pallet for things like a "BackgroundBrush" or "ShadowBrush".
My dilemma is this: in the BackgroundBrush() method I believe it's better (performance-wise) to say something like:
if( _backgroundBrush == null ) _backgroundBrush = new SolidBrush(....); // test nullness and throw exception here if necessary return _backgroundBrush;
The problem arises if the client code makes the following call:
using( Brush backgroundBrush = pallet.BackgroundBrush) { // do something with brush }
My cached brush is now invalid for subsequent calls to BackgroundBrush. This exception to normal coding practice has to be communicated and I know that it's just asking for trouble.
Since the creation of brushes take time, I'd rather have the Pallet object implement IDisposable. When the system needs the picture drawn, it creates the Surface object and the pallet and wraps these with using() statements. Using this method, each gdi+ object is created at the last possible moment and disposed at the last responsible moment. This caching isn't a problem in my usual apps with databases because the real time it takes to create a connection is cached by the system - therefore I always dispose every connection and downstream object. But this need is different. I just don't like having a bunch of objects being returned that implement IDisposable but shouldn't have their .Dispose() function called - it just feels like a really bad code-smell waiting to happen .
I suppose I could solve the problem by returninf an abstracted object, thereby pushing the actual object brush up into the framework , but I'm not there yet in terms of justifying that object.