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
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
Something to bear in mind!