2014-05-14 86 views
2

我有以下的轉換器在我的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

你爲什麼不問你的代碼審查? –

+0

我做到了;以下是他的迴應:「如果可以的話,我寧願放棄它,儘管我對imageource不夠熟悉並知道如何實現這一點。」 (我可能是我的團隊中最熟悉的WPF)。我想我會跟進更多的觀衆,以確保我們的理由是正確的。 –

回答

2

BitmapImage.StreamSource文檔說:如果你想創建的BitmapImage後關閉流

設置CacheOption屬性BitmapCacheOption.OnLoad。默認的OnDemand緩存選項保留對流的訪問權限,直到需要位圖,並且垃圾收集器處理清理。

既然你設置CacheOption因此,imgBrush應該不再需要後EndInit(至少,這就是我會解釋引用的段落),讓你的代碼看起來正確的我訪問流。


PS:是的,這是很好的做法,處理所有IDisposable S,但是,你的情況,它只是一個內存流。與文件流或數據庫連接相比,內存流沒有任何需要釋放的非託管資源。實際上,根據reference sourceMemoryStream.Dispose所做的就是確保在嘗試再次讀取時引發異常,這樣我就不會失去任何睡眠。

0

在內部,

EndInit() 

函數將調用

FinalizeCreation() 

從流(如果設置)加載數據。 然後你可以放棄你的記憶流而不用擔心。 通常是一個很好的做法,明確地處理這樣的ref。