Is re-using GDI+ objects bad practice? (or: How to use many nested using blocks without getting headaches?)

StackOverflow https://stackoverflow.com/questions/1491645

Question

I'm currently writing a fairly complex paint method for a user control, involving a fair amount of drawing code. I know that all GDI+ resources need to be properly disposed so I wrap each of those in a using block.

But when I noticed that I used three using blocks for three different SolidBrushes I wondered whether I couldn't just re-use them. Create a SolidBrush, draw with it, assign a different color, draw something else, etc. And put a Dispose() at the end.

Is such a thing advisable or am I thinking too hard here? I don't particularly like too many using blocks nested in each other as well. While a nice pattern it hinders readability at times.

Was it helpful?

Solution

Well, re-using is an optimization and it is probably premature and therefore: Yes it is a bad practice. I would wait for a clear performance problem to surface and then look for the bottleneck. You would be trading some (unknown) performance gains for the rapidly increasing complexity of managing the state of those components.

On a side note, one pretty much accepted form of nesting using-blocks looks like this:

 using (var a = ...)
 using (var b = ...)
 using (var c = ...)
 {

 }

OTHER TIPS

I think there is nothing bad with this practice. But i think you can reuse the created Brushes. In my own UserControls, if i use Brushes i store them in a local variable of the UserControl and dispose them of when i dispose the UserControl.

public class MyUserControl : UserControl{

  private SolidBrush _brush;

  public MyUserControl() {
    _brush = new SolidBrush(Color.Red);
  }

  protected override void OnPaint(PaintEventArgs e){
    // Draw with the brush;
  }

  protected override void Dispose(bool disposing){
    // other Dispose logic
    if (_brush != null) {
      _brush.Dispose();
    }
  }
}

Re-using GDI objects is not bad in itself. What is bad is when there are too many GDI objects in existence at one time than your graphics card GDI can handle.

I had earlier faced a problem as a result of caching a dashed pen and some brushes. My colleague's code (running within the same WM_PAINT) had no problems at all even though it did not cache any objects! Only my oversmartness was causing GDI to choke up and throw an OutOfMemoryException (they probably mean out of memory on the graphics card).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top