C # GDI +, creating LinearGradientBrush in a loop (memory leak)

Today I am faced with a dilemma. I created an application that uses GDI + to draw on a form. The drawing is started by a timer every second. The draw method uses a for loop to iterate over a set of objects, and if they have a certain state, draw them.

I want to paint them with LinearGradientBrush simply because it looks much better than a simple brush. Look at the following

//minutes foreach (Led l in MinuteGrid.Leds) { LinearGradientBrush b = new LinearGradientBrush (l.LedRectangle, Color.GreenYellow, Color.Green, 110); if (l.IsLit) g.FillRectangle(b, l.LedRectangle); b.Dispose(); } 

I create a new LinearGradientBrush for each iteration of the loop (which bothers me), but that is because I have to. I cannot create one outside the loop because its set of constructors requires me to set parameters that are only ever known inside the loop.

I found that using the dispose method on a LinearGradientBrush object is not so reliable. If I run the application and view it in the task manager, its memory will be ejected. When I then add the line b = null, which seems to be very helpful as follows

  foreach (Led l in MinuteGrid.Leds) { LinearGradientBrush b = new LinearGradientBrush (l.LedRectangle, Color.GreenYellow, Color.Green, 110); if (l.IsLit) g.FillRectangle(b, l.LedRectangle); if (b != null) { b.Dispose(); b = null; } } 

I'm just wondering if there is a better way to work with LinearGradientBrushes? Or is there a better solution to use?

Many thanks

+1
c # gdi +
source share
4 answers

I would recommend using the "using" statement:

 foreach (Led l in MinuteGrid.Leds) { if (l.IsLit) { using(LinearGradientBrush b = new LinearGradientBrush(l.LedRectangle, Color.GreenYellow, Color.Green, 110)) { g.FillRectangle(b, l.LedRectangle); } } } 

However, remember Dispose () does not free (manage) memory . It just frees unmanaged resources (which is important and may include unmanaged memory). The memory will not be freed until the GC starts up, which may not happen during the cycle.

However, if the memory pressure gets too high, the garbage collector should work inside your loop and you will see that it drops. This is how .NET is designed - just accept it and don’t worry. GC will eventually collect this memory, so there is nothing to worry about.

+6
source share

Add a gradient brush for each Led. If you cannot add it to this class, you can use the Dictionary <Led, GradientBrush> dictionary to store brushes to get easy access to them. So you only need one brush on Led instead of one iteration of the loop,

(Also, in your code example, it makes no sense to create a brush if! L.IsLit)

0
source share

Dispose has nothing to do with freeing up managed memory. This is completely handled by the GC, which runs "when necessary." However, since the brush most likely contains a pen, you must discard it. I would recommend that you do this in the using block instead of manually calling Dispose , as this will make sure Dispose is called even if there is an exception.

0
source share

If the number of permutations is limited, you can simply pre-create all your brushes:

 LinearGradientBrush rectGreenBrush = new LinearGradientBrush(l.LedRect........); LinearGradientBrush rectRedBrush = new LinearGradientBrush(l.LedRect........); foreach (Led l in MinuteGrid.Leds) { LinearGradientBrush b = null; if (xxx) b = rectGreenBrush; else if (yyyy) b = rectRedBrush; else..... do painting } cleanup brushes 

The second option is similar, but for creating brushes as needed;

 List<LinearGradientBrush> createdBrushes = new List<LinearGradientBrush>(); foreach (Led l in MinuteGrid.Leds) { LinearGradientBrush b = null; b = FindOrCreateBrushBasedOnLed(l, createdBrushes); // if not already created, creates the brush and adds it to the list do painting } foreach (LinearGradientBrush b in createdBrushes) { cleanup brushes } 

The other answers are true that .NET can allow the use of managed memory in a balloon until it does no harm. But this should help to carve a lot of creation / deletion if there are many Led objects that will go through.

0
source share

All Articles