Consider the following code
Dim bitmap As New Drawing.Bitmap(fileName) Return bitmap
It certainly looks fairly innocuous but it had a problem, or rather it caused a problem further down the track. We wanted to replace some of the image files that we had previously loaded into the application. But trying to do that threw an exception telling us “The process cannot access the file '…’ because it is being used by another process.”. Which wasn’t entirely accurate, actually we couldn’t access the file because it was in use by this process. But nitpicking aside, the reason for this was the Bitmap constructor above which loads the file but doesn’t unlock it, only a call to Bitmap.Dispose() unlocks it again.
So my first attempt to fix this looked something like this
Dim fs As New FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) Dim bitmap As New Drawing.Bitmap(fs) fs.Close() Return bitmap
Since this opened the image via a FileStream and closed it afterwards, this should solve the problem. And it did on my Windows 7 machine, but it caused even bigger problems on a Windows XP machine. We started getting an out of memory exception for no apparent reason.
I eventually came to the conclusion that this was down to the Bitmap constructor that took a FileStream instance. When it’s passed a file name, it can make a pretty good guess at what kind of file it’s loading based on the extension, but when it is just given a bunch of bytes, it has to make a guess as to what type of image it’s looking at and I presume the heuristics in XP weren’t as good as they are in Windows 7. I’m guessing here, since all this happens in the guts of the GDI+ API.
So my final attempt at fixing this looks like this
Dim fileBitmap As New Drawing.Bitmap(fileName) Dim bitmap As New Drawing.Bitmap(fileBitmap) fileBitmap.Dispose() Return bitmap
Which so far hasn’t caused any more issues…
1 comment:
That works...
Thanks.
Post a Comment