C
Chris Dunaway
When working with GDI+, calling the CreateGraphics method to draw on a
control has normally been frowned upon and it is always emphasized to
dispose of pens and brushes and other GDI objects lest you run out.
But consider the following code (in a timer elapsed event on a Windows
Form):
private void TimerFunc(object sender, System.Timers.ElapsedEventArgs
e) {
Graphics gdi = this.CreateGraphics();
int x, y;
int w, h;
int r, g, b;
x = _random.Next(0, this.ClientRectangle.Width + 1);
y = _random.Next(0, this.ClientRectangle.Height + 1);
w = _random.Next(5, 250);
h = _random.Next(5, 250);
r = _random.Next(0, 256);
g = _random.Next(0, 256);
b = _random.Next(0, 256);
Pen p = new Pen(Color.FromArgb(255, r, g, b));
gdi.DrawEllipse(p, x, y, w, h);
}
Note that I am calling CreateGraphics and creating a new Pen without
disposing of either. This method handles a Timer Elapsed event. I
set the interval of the timer to 50ms. So basically, i draw random
ellipses on the form.
But when I montior the app in Task Manager, Process explorer, or a GDI
monitor, the number of GDI objects does not change. They do not go
up, even if I let the code run for minutes at a time. I even added
the following loop in the elapsed event:
List<Pen> penList = new List<Pen>(50000)
for (int i = 0;i <= 50000;i++) {
penList.Add(new Pen(Color.FromArgb(255, r, g, b));
}
Even after creating 50000 new Pens, the GDI object count did not
change! Memory usage increased (Working Set size) slightly but not in
significant amounts for the duration of this test.
Can anyone explain this behavior? I expected to see the GDI object
count increase since I did not dispose of any of the objects. My
understanding was that the gc only triggered on memory pressure and
not handle pressure.
Why bother disposing of pens and brushes and the like if it doesn't
seem to have an effect on the GDI handle count? Have I missed
something obvious?
Thanks for any insight!
Chris
control has normally been frowned upon and it is always emphasized to
dispose of pens and brushes and other GDI objects lest you run out.
But consider the following code (in a timer elapsed event on a Windows
Form):
private void TimerFunc(object sender, System.Timers.ElapsedEventArgs
e) {
Graphics gdi = this.CreateGraphics();
int x, y;
int w, h;
int r, g, b;
x = _random.Next(0, this.ClientRectangle.Width + 1);
y = _random.Next(0, this.ClientRectangle.Height + 1);
w = _random.Next(5, 250);
h = _random.Next(5, 250);
r = _random.Next(0, 256);
g = _random.Next(0, 256);
b = _random.Next(0, 256);
Pen p = new Pen(Color.FromArgb(255, r, g, b));
gdi.DrawEllipse(p, x, y, w, h);
}
Note that I am calling CreateGraphics and creating a new Pen without
disposing of either. This method handles a Timer Elapsed event. I
set the interval of the timer to 50ms. So basically, i draw random
ellipses on the form.
But when I montior the app in Task Manager, Process explorer, or a GDI
monitor, the number of GDI objects does not change. They do not go
up, even if I let the code run for minutes at a time. I even added
the following loop in the elapsed event:
List<Pen> penList = new List<Pen>(50000)
for (int i = 0;i <= 50000;i++) {
penList.Add(new Pen(Color.FromArgb(255, r, g, b));
}
Even after creating 50000 new Pens, the GDI object count did not
change! Memory usage increased (Working Set size) slightly but not in
significant amounts for the duration of this test.
Can anyone explain this behavior? I expected to see the GDI object
count increase since I did not dispose of any of the objects. My
understanding was that the gc only triggered on memory pressure and
not handle pressure.
Why bother disposing of pens and brushes and the like if it doesn't
seem to have an effect on the GDI handle count? Have I missed
something obvious?
Thanks for any insight!
Chris