我的WPF应用程序中有以下转换器:
[ValueConversion(typeof(byte[]), typeof(ImageSource))]
public class ReturnLabelImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var byteArray = value as byte[];
if (byteArray == null)
return new BitmapImage();
return BuildReturnLabelImageSource(byteArray);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public static ImageSource BuildReturnLabelImageSource(byte[] image)
{
if (image == null)
return null;
var imgBrush = new BitmapImage
{
CacheOption = BitmapCacheOption.OnLoad,
CreateOptions = BitmapCreateOptions.PreservePixelFormat
};
imgBrush.BeginInit();
imgBrush.StreamSource = ConvertImageToMemoryStream(image);
imgBrush.EndInit();
return imgBrush;
}
public static MemoryStream ConvertImageToMemoryStream(byte[] img)
{
var ms = new MemoryStream(img);
return ms;
}
}
我的代码审核员给了我一个关于流应该被处理掉的建议。我不应该明白我应该怎么做;我想出的最好的想法是:
public static ImageSource BuildReturnLabelImageSource(byte[] image)
{
if (image == null)
return null;
var imgBrush = new BitmapImage
{
CacheOption = BitmapCacheOption.OnLoad,
CreateOptions = BitmapCreateOptions.PreservePixelFormat
};
using (var stream = ConvertImageToMemoryStream(image))
{
imgBrush.BeginInit();
imgBrush.StreamSource = stream;
imgBrush.EndInit();
return imgBrush;
}
}
我是在正确的轨道上,还是我应该这样做?
答案 0 :(得分:2)
如果要在创建BitmapImage后关闭流,请将CacheOption属性设置为BitmapCacheOption.OnLoad。默认的OnDemand缓存选项保留对流的访问,直到需要位图,并且清理由垃圾收集器处理。
由于您相应地设置了CacheOption
,imgBrush
应该不再需要在EndInit
之后访问流(至少,这就是我将如何解释引用的段落),因此您的代码看起来如此对我而言。
PS:是的,最好处置所有IDisposable
,但在你的情况下,它只是一个内存流。与文件流或数据库连接相反,内存流没有任何需要释放的非托管资源。事实上,根据reference source,MemoryStream.Dispose
所做的就是确保在你尝试再次读取它时抛出异常,这样我就不会失去任何睡眠。
答案 1 :(得分:0)
在内部,
EndInit()
函数将调用
FinalizeCreation()
从流中加载数据(如果已设置)。 然后你可以毫无顾虑地处理你的记忆流。 通常这是一个很好的做法,明确地处理这样的参考。