2012-07-05 120 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