Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disposing a memory stream properly (WPF Image Conversion)

Tags:

c#

.net

image

wpf

Can anyone tell me how to best dispose of a memory stream? previously, I had this and everything worked fine:

MemoryStream strmImg = new MemoryStream(profileImage.Image);
BitmapImage myBitmapImage = new BitmapImage();
myBitmapImage.BeginInit();
myBitmapImage.StreamSource = strmImg;
myBitmapImage.DecodePixelWidth = 200;
myBitmapImage.DecodePixelWidth = 250;
myBitmapImage.EndInit();
this.DemographicInformation.EmployeeProfileImage = myBitmapImage;

I later realized, that I'm going to have a memory leak as the MemoryStream implements IDisposable and should be disposed of after I use it, which led me to this implementation:

using(MemoryStream strmImg = new MemoryStream(profileImage.Image))
{
    BitmapImage myBitmapImage = new BitmapImage();
    myBitmapImage.BeginInit();
    myBitmapImage.StreamSource = strmImg;
    myBitmapImage.DecodePixelWidth = 200;
    myBitmapImage.DecodePixelWidth = 250;
    myBitmapImage.EndInit();
    this.DemographicInformation.EmployeeProfileImage = myBitmapImage;
}

The Problem is in this line of code:

 myBitmapImage.StreamSource = strmImg;

My assumption is this is referencing the memory location, and the dispose obviously cleans up that location, and it worked in the past because it was never disposed of properly.

My question is, how do I use MemoryStream and dispose it properly after use, while still keeping the converted data (Image) that I need?

like image 295
Roka Avatar asked Feb 09 '23 15:02

Roka


1 Answers

You need to add this line:

myBitmapImage.CacheOption = BitmapCacheOption.OnLoad;

Which caches the entire image into memory at load time. Without this line, the default value of the CacheOption property is OnDemand which retains access to the stream until the image is needed. So your code should be:

using(MemoryStream strmImg = new MemoryStream(profileImage.Image))
{
    BitmapImage myBitmapImage = new BitmapImage();
    myBitmapImage.BeginInit();
    myBitmapImage.CacheOption = BitmapCacheOption.OnLoad;
    myBitmapImage.StreamSource = strmImg;
    myBitmapImage.DecodePixelWidth = 200;
    myBitmapImage.DecodePixelWidth = 250;
    myBitmapImage.EndInit();
    this.DemographicInformation.EmployeeProfileImage = myBitmapImage;
}
like image 65
Racil Hilan Avatar answered Feb 11 '23 13:02

Racil Hilan