2012-07-05 100 views
4

我使用此代碼將圖像從二進制轉換爲圖像。如何清除內存流

public class ImageConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     var memStream = new MemoryStream(((MeetPoint_B2C.ServiceReference1.Binary)value).Bytes); 
     memStream.Seek(0, SeekOrigin.Begin); 
     var empImage = new BitmapImage(); 
     empImage.CreateOptions = BitmapCreateOptions.None; 
     empImage.SetSource(memStream); 
     return empImage; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

我從我的數據庫加載超過20圖像時有錯誤。 這是異常未處理。該請求不受支持。 我認爲內存流已滿。那麼如何重置內存流呢?我知道可以使用dispose()memorystream.setLength0但是如何或應該在哪裏放置編碼?

異常詳細信息

 
System.OutOfMemoryException was unhandled 
    Message=OutOfMemoryException 
    StackTrace: 
     at MS.Internal.FrameworkCallbacks.NotifyManagedDebuggerOnNativeOOM() 
     at MS.Internal.XcpImports.BitmapSource_SetSourceNative(IntPtr bitmapSource, CValue& byteStream) 
     at MS.Internal.XcpImports.BitmapSource_SetSource(BitmapSource bitmapSource, CValue& byteStream) 
     at System.Windows.Media.Imaging.BitmapSource.SetSourceInternal(Stream streamSource) 
     at System.Windows.Media.Imaging.BitmapImage.SetSourceInternal(Stream streamSource) 
     at System.Windows.Media.Imaging.BitmapSource.SetSource(Stream streamSource) 
     at MeetPoint_B2C.ImageConverter.Convert(Object value, Type targetType, Object parameter, CultureInfo culture) 
     at System.Windows.Data.BindingExpression.ConvertToTarget(Object value) 
     at System.Windows.Data.BindingExpression.GetValue(DependencyObject d, DependencyProperty dp) 
     at System.Windows.DependencyObject.EvaluateExpression(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry) 
     at System.Windows.DependencyObject.EvaluateBaseValue(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, ValueOperation operation) 
     at System.Windows.DependencyObject.EvaluateEffectiveValue(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry newEntry, ValueOperation operation) 
     at System.Windows.DependencyObject.UpdateEffectiveValue(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, ValueOperation operation) 
     at System.Windows.DependencyObject.RefreshExpression(DependencyProperty dp) 
     at System.Windows.Data.BindingExpression.RefreshExpression() 
     at System.Windows.Data.BindingExpression.SendDataToTarget() 
     at System.Windows.Data.BindingExpression.SourceAcquired() 
     at System.Windows.Data.BindingExpression.System.Windows.IDataContextChangedListener.OnDataContextChanged(Object sender, DataContextChangedEventArgs e) 
     at System.Windows.Data.BindingExpression.DataContextChanged(Object sender, DataContextChangedEventArgs e) 
     at System.Windows.FrameworkElement.OnDataContextChanged(DataContextChangedEventArgs e) 
     at System.Windows.FrameworkElement.OnAncestorDataContextChanged(DataContextChangedEventArgs e) 
     at System.Windows.FrameworkElement.NotifyDataContextChanged(DataContextChangedEventArgs e) 
     at System.Windows.FrameworkElement.OnAncestorDataContextChanged(DataContextChangedEventArgs e) 
     at System.Windows.FrameworkElement.NotifyDataContextChanged(DataContextChangedEventArgs e) 
     at System.Windows.FrameworkElement.OnTreeParentUpdated(DependencyObject newParent, Boolean bIsNewParentAlive) 
     at System.Windows.DependencyObject.UpdateTreeParent(IManagedPeer oldParent, IManagedPeer newParent, Boolean bIsNewParentAlive, Boolean keepReferenceToParent) 
     at MS.Internal.FrameworkCallbacks.ManagedPeerTreeUpdate(IntPtr oldParentElement, IntPtr parentElement, IntPtr childElement, Byte bIsParentAlive, Byte bKeepReferenceToParent, Byte bCanCreateParent) 
     at MS.Internal.XcpImports.Measure_WithDesiredSizeNative(IntPtr element, Single inWidth, Single inHeight, Single& outWidth, Single& outHeight) 
     at MS.Internal.XcpImports.UIElement_Measure_WithDesiredSize(UIElement element, Size availableSize) 
     at System.Windows.UIElement.Measure_WithDesiredSize(Size availableSize) 
     at System.Windows.Controls.VirtualizingStackPanel.MeasureChild(UIElement child, Size layoutSlotSize) 
     at System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(Size constraint) 
     at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Double inWidth, Double inHeight, Double& outWidth, Double& outHeight) 
     at MS.Internal.XcpImports.MeasureOverrideNative(IntPtr element, Single inWidth, Single inHeight, Single& outWidth, Single& outHeight) 
     at MS.Internal.XcpImports.FrameworkElement_MeasureOverride(FrameworkElement element, Size availableSize) 
     at System.Windows.FrameworkElement.MeasureOverride(Size availableSize) 
     at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Double inWidth, Double inHeight, Double& outWidth, Double& outHeight)

這是使用以下.xaml

<Grid.Resources> 
    <src:ImageConverter x:Key="imgConverter"/> 
</Grid.Resources> 
<Image Grid.Column="1" Grid.Row="4" Height="136" HorizontalAlignment="Left" 
    Margin="16,16,0,0" Name="imgEmp" Stretch="Fill" 
    VerticalAlignment="Top" Width="200" 
    Source="{Binding Image, Converter={StaticResource imgConverter}}"/> 
+0

您確定由於通話次數而不是特定圖像而失敗嗎? – 2012-07-05 12:54:37

+2

您每次都使用不同的內存流,因此您不需要重置任何內容。異常是由於其他原因,嘗試將代碼封裝在異常處理程序中並轉換爲異常。 – 2012-07-05 12:55:56

+0

現在還不清楚上下文是什麼 - 如果這是一個WCF *服務器*,使用WPF類相對不常見...... – 2012-07-05 12:59:39

回答

3

由於BitmapImage對象採用流的所有權,那麼您將無法關閉(或處置)正確,所以我建議沿着線的東西:

public BitmapImage Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
{ 
    var empImage = new BitmapImage(); 
    empImage.CreateOptions = BitmapCreateOptions.None; 
    empImage.SetSource(new MemoryStream(((MeetPoint_B2C.ServiceReference1.Binary)value).Bytes);); 
    return empImage; 
} 

在調用的方法,實施自己的資源清理。 BitmapImage不會實現IDisposable,所以不能使用using語句。微軟應該考慮實現IDisposable接口時,它清楚地包含非託管資源的引用:

public void ConvertBitmap() 
{ 
    BitmapImage img = null; 
    try 
    { 
     img = Convert(// pass in your params); 

     // do stuff with your img 
    } 
    finally 
    { 
     // dispose of the memorystream in case of exception 
     if(img != null && img.StreamSource != null) img.StreamSource.Dispose(); 
    } 
} 

這將確保原始MemoryStream即使在例外的情況下,適當地清理。

2

你已經創建你被問到轉換一個新的MemoryStream每一次 - 雖然你不應該需要在這種情況下尋求。你不需要重置任何東西。

你真的應該找出究竟被拋出什麼異常 - 這可能是沒什麼做是內存不足。您已編輯問題以顯示堆棧跟蹤,但不是拋出異常的類型。一種可能性是,如果你的問題標籤是任何需要的東西,那麼這與在WCF服務中使用WPF控件有關。

編輯:請注意,即使你不想處置MemoryStream,你應該確保你處置BitmapImage結果,當你用它做。不幸的是,我們沒有足夠的背景知道你在做什麼來提供有關這方面的任何建議。

+0

但有一次我要轉換許多圖像,所以它已經拋出了我這個錯誤。 – 2012-07-05 13:01:48

+0

@ user1504015:對不起,我不明白你在說什麼。請重新修飾它。 – 2012-07-05 13:08:55

+0

編碼運行良好,當我加載大約20圖像..但它發生上面的錯誤時,它> 20圖像。 – 2012-07-05 13:16:18