我可以处理这个流吗?

时间:2014-05-14 14:30:40

标签: c# wpf memorystream

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

我是在正确的轨道上,还是我应该这样做?

2 个答案:

答案 0 :(得分:2)

BitmapImage.StreamSource的文档说:

  

如果要在创建BitmapImage后关闭流,请将CacheOption属性设置为BitmapCacheOption.OnLoad。默认的OnDemand缓存选项保留对流的访问,直到需要位图,并且清理由垃圾收集器处理。

由于您相应地设置了CacheOptionimgBrush应该不再需要在EndInit之后访问流(至少,这就是我将如何解释引用的段落),因此您的代码看起来如此对我而言。


PS:是的,最好处置所有IDisposable,但在你的情况下,它只是一个内存流。与文件流或数据库连接相反,内存流没有任何需要释放的非托管资源。事实上,根据reference sourceMemoryStream.Dispose所做的就是确保在你尝试再次读取它时抛出异常,这样我就不会失去任何睡眠。

答案 1 :(得分:0)

在内部,

EndInit() 

函数将调用

FinalizeCreation()

从流中加载数据(如果已设置)。 然后你可以毫无顾虑地处理你的记忆流。 通常这是一个很好的做法,明确地处理这样的参考。