I'm facing a memory leak issue. The leak comes from here:
public static BitmapSource BitmapImageFromFile(string filepath)
{
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.CacheOption = BitmapCacheOption.OnLoad; //here
bi.CreateOptions = BitmapCreateOptions.IgnoreImageCache; //and here
bi.UriSource = new Uri(filepath, UriKind.RelativeOrAbsolute);
bi.EndInit();
return bi;
}
I have a ScatterViewItem
, which contains an Image
, and the source is the BitmapImage
of this function.
The actual thing is a lot more complex than this, so I can't simply put an Image into it. I also can't use the default load options, as the image file might be deleted and hence will face some permission issue accessing the file during deletion.
The problem occurs when I close the ScatterViewItem
, which in turn closes the Image
. However, the cached memory isnt cleared. So after many cycles, the memory consumption is pretty big.
I tried setting image.Source=null
during the Unloaded
function, but it didn't clear it.
How do I clear the memory correctly during unloading?
I found the answer here. Seems like it's a bug in WPF.
I modified the function to include Freeze
:
public static BitmapSource BitmapImageFromFile(string filepath)
{
var bi = new BitmapImage();
using (var fs = new FileStream(filepath, FileMode.Open))
{
bi.BeginInit();
bi.StreamSource = fs;
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.EndInit();
}
bi.Freeze(); //Important to freeze it, otherwise it will still have minor leaks
return bi;
}
I also create my own Close function, which will be called before I close the ScatterViewItem
:
public void Close()
{
myImage.Source = null;
UpdateLayout();
GC.Collect();
}
Because myImage
is hosted in a ScatterViewItem
, GC.Collect()
must be called before the parent is closed. Otherwise, it will still linger in memory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With