views:

154

answers:

2

As an example:

using (Brushes.Black) { ... }

is not a good idea, because it is static. The next time your app goes to use Brushes.Black, you'll have problems, because it has been disposed.

Now, if you're only using Brushes.Black, then it's probably ok to not dispose it, because you're only leaving one unmanaged resource (hopefully!) lying around.

But, in general, should you avoid using lots of static IDisposables, or is there something I'm missing?

A: 

Normally just use them, and let the framework class worry about disposing them.

They are there so that you can use them without creating and disposing them each time. Each one is created when you first use it, and is cached in a hash table. The framework class is responsible for disposing them properly when the application closes.

There aren't really that many static IDisposables that you should need to worry about them. If you would use an awful lot of brushes, you would probably create them from a color in a loop anyway (and then you would of course be responsible for disposing them).

Guffa
I'm surprised you didn't get any comments on this.Normally people feel pretty strongly about always disposing IDisposable objects.But, I guess in the case of static IDisposables, the quideline should be "Don't dispose of them, and don't use a lot of them."
mbeckish
You should dispose the objects that you own yourself, but as the Brushes class owns the Brush instances, you can't dispose them. Making so would make the Brushes class contain references to unusable objects.
Guffa
+2  A: 

As an example:

using (Brushes.Black) { ... }

is not a good idea, because it is static. The next time your app goes to use Brushes.Black, you'll have problems, because it has been disposed.

It's not just a static field - The property runs code actively in order to create new instances when needed. Just look at the corresponding Code (Reflector):

public static Brush Black
{
    get
    {
        Brush brush = (Brush) SafeNativeMethods.Gdip.ThreadData[BlackKey];
        if (brush == null)
        {
            brush = new SolidBrush(Color.Black);
            SafeNativeMethods.Gdip.ThreadData[BlackKey] = brush;
        }
        return brush;
    }
}
Dario
I've actually run into problems with using (Brushes.Black) { ... } when it is in a tight loop - maybe it's not being set to null right away?
mbeckish
+1 disposable objects should be disposed by their owner. This code from reflector shows that the caller is the owner.
Wim Coenen
@wcoenen - I agree when you are talking about your own local instance of an object. However, since this is static, you have to be able to guarantee that no code anywhere in your app, at any time in the future, will need to use it before you can safely dispose. Now, according to Reflector, this shouldn't be an issue in this case, because if the brush is null, it will make a new one. However, as I mentioned in the first comment to this answer, it doesn't always seem to work, at least if you just use a 'using' statement, and don't explicitly set it to null.
mbeckish
@mbeckish: Disposing the object will never set the reference to null, so the Brushes class won't know that it has to recreate the objects. @wcoenen: No, the caller is not the owner, the Brushes class is the owner. It keeps a reference to the object.
Guffa