Don't create too many Icons
Here’s a fun little gotcha.
I was creating a list of files, displayed to the user.
Alongside each file I was displaying the icon associated with the file type; fetching it using SHGetFileInfo
, storing the Icon
instance in the ViewModel for each file entry, then converting that to a BitmapSource
using a converter on the binding.
Should be fine, right?
And it was fine, until a user tried to list a few thousand files.
At this point some very werid stuff started happening: OutOfMemoryExceptions
which didn’t crash the application, HRESULT 0x88982F94
from Imaging.CreateBitmapSourceFromHIcon
, Icon.FromHandle
throwing ArgumentException
, and some others.
It turns out that I was running out of GDI handles (if you want to see how many GDI handles your application is using, open Task Manager, Details, and show the “GDI objects” column). Each application appears to have about 10,000 GDI handles available (depending on various factors, as far as I can determine), and running out of them is a Very Bad Thing (with weird and varied symptoms), and appeared to be happening after a few thousand Icon instances were created.
Indeed, Icon does own a GDI handle, so there’s a hard limit on how many Icon instances you can keep around.
Fixing it was easy: keep the Icon
instance only long enough to convert it to an ImageSource
, then dispose it (and store the ImageSource
in the ViewModel instead of the Icon
).
Something to bear in mind!