正确处理内存流 (WPF 图像转换)

4

有人能告诉我如何最好地处理内存流吗?之前,我有以下代码并且一切正常:

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;

后来我意识到,由于MemoryStream实现了IDisposable接口并应该在使用完毕后进行释放,我会遇到内存泄漏问题,因此我采用了以下实现方式:

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;
}

问题出在这行代码中:
 myBitmapImage.StreamSource = strmImg;

我的假设是这个引用的是内存位置,而dispose明显清理了那个位置,过去之所以起作用是因为它从未被正确处理。

我的问题是,我如何在使用MemoryStream并在使用后正确处理它时,仍然保留所需的转换数据(Image)?


1
请注意,Dispose MemoryStream是一个好的编程习惯(因为它是可处理的),但如果不这样做,它实际上并不会泄漏。特别地,Dispose并不会真正释放内存;只有在GC回收MemoryStream时才会发生。由于BitmapImage保留对MemoryStream的引用,因此只有在BitmapImage被回收之后,MemoryStream才能被回收。 - Dan Bryant
1个回答

8
你需要添加这一行代码:
myBitmapImage.CacheOption = BitmapCacheOption.OnLoad;

该代码行会在加载时将整个图像缓存到内存中。如果没有这个代码行,则CacheOption属性的默认值为OnDemand,它会在需要使用图像时保留对流的访问权。因此,您的代码应该如下:

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;
}

运行得非常好。谢谢! - Roka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接