Re: [Bug Suspicion] So, <any_gdi_object>.Dispose() does ... what exactly?

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance

From: Philipp Schumann (phil_at_mokka.org)
Date: 02/23/05


Date: Wed, 23 Feb 2005 01:41:01 -0000

In fact, this seems to be a general pattern, although the same for .NET
applications has not been reported so far: according to
http://home.wxs.nl/~sjaak.priester/golive/crashes.html#taskman and other
stuff easily found when googling for "9999 gdi", Windows seems to refuse to
grant more than 9999 GDI objects to any application, unless previously
granted GDI objects are properly released. Something is preventing my and
Robbe's code from doing so, and looking at it, you can tell immediately it
surely isn't the code itself!

So while GoLive freezes the system when this happens, all that happens in a
.NET application is a mere Exception which can be caught and certainly won't
freeze anything, caught or not. Now, that's quite some progress already---if
only we could find out just what the cause of the problem is!

"Philipp Schumann" <phil@mokka.org> schrieb im Newsbeitrag
news:uH7htcUGFHA.3664@TK2MSFTNGP15.phx.gbl...
> Hi Robbe,
>
> After running your program for just a little over one hour, your tray icon
> disappears. (Because you catch the exception and return null in the icon
> drawing routine, null is assigned to the NotifyIcon every second from this
> point onwards.) As this happens, the "GDI objects" indicator in the task
> manager reads "9996". It will stay at this value from now on, and raise
> generic GDI+ exceptions every time the code wants to do something.
>
> So your program is showing exactly the same symptoms as mine which means
> one of the following two is true:
>
> 1) it is an issue specific to some machine or framework configs
> 2) it is a well-hidden framework bug
> 3) we have both made the same "mistake" that just cannot be found even by
> inspecting our codes time and again
>
> Let's see what happens next...
>
>
> "Robbe Morris [C# MVP]" <info@turnkeytools.com> schrieb im Newsbeitrag
> news:uKWbOvTGFHA.1740@TK2MSFTNGP09.phx.gbl...
>>I did not see this when I wrote an article for drawing icons from
>> scratch for the system tray.
>>
>> http://www.eggheadcafe.com/articles/createiconsforsystemtray.asp
>>
>> --
>> 2005 Microsoft MVP C#
>> Robbe Morris
>> http://www.robbemorris.com
>> http://www.mastervb.net/home/ng/forumvbcode/post10017013.aspx
>> http://www.eggheadcafe.com/articles/adonet_source_code_generator.asp
>>
>>
>>
>> "Philipp Schumann" <phil@mokka.org> wrote in message
>> news:uIukmiPGFHA.1932@TK2MSFTNGP14.phx.gbl...
>>> Hi,
>>>
>>> I have developed a very small Windows application which creates a new
>>> Icon using .NET GDI+ every second (or every minute, that's
>>> user-definable). I need to do this because my "drawing surface" is a
>>> system tray icon so I can't just paint to a control or something.
>>> However, whenever I replace the NotifyIcon.Icon property, whether it is
>>> every second or every minute, I dispose of the previous icon. I also
>>> dispose all GDI+ objects (Bitmap, Graphics, Brush, Pen) while drawing
>>> the icon, using using{} clauses.
>>>
>>> I have double- and triple-checked that everything is disposed of in my
>>> code. Now, while I keep the application running, when I open the task
>>> manager (ctrl+alt+del) and make sure the "GDI objects" column is
>>> visible, I have to realize that either every second or every minute,
>>> depending on aforementioned user option, that number increases by 6. If
>>> the app has run for a few hours, creating a new icon every second, the
>>> number approaches several thousands, and eventually every time I call
>>> Bitmap.GetHicon () to convert my image to an Icon raises the "A general
>>> error occured in GDI+." exception. I suspect that is because an upper
>>> limit of GDI handles had been allocated by the application - after all,
>>> it doesn't seem to free the unused (disposed) handles of previous GDI
>>> objects (remember that's six per second/minute, so it can't just be the
>>> icon handle). However, the memory consumption of the app remains
>>> constantly between 6 and 14 MB, typical for a small .NET app, so
>>> Dispose() still seems to work correctly with regard to freeing up
>>> memory.
>>>
>>> Now, the application is not mission-critical, it's just a small, silly
>>> clock for the system tray, so if this occurs, the simple workaround of
>>> starting a new instance of the application and then immediately exiting
>>> the current instance works fine and, from the "user's" point of view,
>>> "resolves" the problem. Still it's a bit nasty and I was wondering
>>> whether anyone has any idea on how to go about it. I have other, more
>>> critical, long-running applications, for example ASP.NET applications,
>>> that make heavy use of the GDI+ drawing and imaging APIs, and if this is
>>> a general bug or so, then these applications could, after one or two
>>> months of running, run into the same sort of problems, couldn't they?
>>>
>>> Many thanks,
>>> Best regards,
>>> Philipp Schumann
>>>
>>> P.S. the clock application and source code can be found at
>>> www.mokka.org/clock if anyone wants to inspect the sources.
>>>
>>
>>
>
>


Quantcast