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 未处理
  消息=OutOfMemoryException
  堆栈跟踪:
       在 MS.Internal.FrameworkCallbacks.NotifyManagedDebuggerOnNativeOOM()
       在 MS.Internal.XcpImports.BitmapSource_SetSourceNative(IntPtr bitmapSource, CValue& byteStream)
       在 MS.Internal.XcpImports.BitmapSource_SetSource(BitmapSource bitmapSource, CValue& byteStream)
       在 System.Windows.Media.Imaging.BitmapSource.SetSourceInternal(流流源)
       在 System.Windows.Media.Imaging.BitmapImage.SetSourceInternal(流流源)
       在 System.Windows.Media.Imaging.BitmapSource.SetSource(流流源)
       在 MeetPoint_B2C.ImageConverter.Convert(对象值,类型 targetType,对象参数,CultureInfo 文化)
       在 System.Windows.Data.BindingExpression.ConvertToTarget(对象值)
       在 System.Windows.Data.BindingExpression.GetValue(DependencyObject d,DependencyProperty dp)
       在 System.Windows.DependencyObject.EvaluateExpression(DependencyProperty 属性,EffectiveValueEntry oldEntry,EffectiveValueEntry & newEntry)
       在 System.Windows.DependencyObject.EvaluateBaseValue(DependencyProperty 属性,EffectiveValueEntry oldEntry,EffectiveValueEntry&newEntry,ValueOperation 操作)
       在 System.Windows.DependencyObject.EvaluateEffectiveValue(DependencyProperty 属性,EffectiveValueEntry oldEntry,EffectiveValueEntry newEntry,ValueOperation 操作)
       在 System.Windows.DependencyObject.UpdateEffectiveValue(DependencyProperty 属性,EffectiveValueEntry oldEntry,EffectiveValueEntry&newEntry,ValueOperation 操作)
       在 System.Windows.DependencyObject.RefreshExpression(DependencyProperty dp)
       在 System.Windows.Data.BindingExpression.RefreshExpression()
       在 System.Windows.Data.BindingExpression.SendDataToTarget()
       在 System.Windows.Data.BindingExpression.SourceAcquired()
       在 System.Windows.Data.BindingExpression.System.Windows.IDataContextChangedListener.OnDataContextChanged(对象发送者,DataContextChangedEventArgs e)
       在 System.Windows.Data.BindingExpression.DataContextChanged(对象发送者,DataContextChangedEventArgs e)
       在 System.Windows.FrameworkElement.OnDataContextChanged(DataContextChangedEventArgs e)
       在 System.Windows.FrameworkElement.OnAncestorDataContextChanged(DataContextChangedEventArgs e)
       在 System.Windows.FrameworkElement.NotifyDataContextChanged(DataContextChangedEventArgs e)
       在 System.Windows.FrameworkElement.OnAncestorDataContextChanged(DataContextChangedEventArgs e)
       在 System.Windows.FrameworkElement.NotifyDataContextChanged(DataContextChangedEventArgs e)
       在 System.Windows.FrameworkElement.OnTreeParentUpdated(DependencyObject newParent,布尔 bIsNewParentAlive)
       在 System.Windows.DependencyObject.UpdateTreeParent(IManagedPeer oldParent,IManagedPeer newParent,布尔 bIsNewParentAlive,布尔 keepReferenceToParent)
       在 MS.Internal.FrameworkCallbacks.ManagedPeerTreeUpdate(IntPtr oldParentElement,IntPtr parentElement,IntPtr childElement,字节 bIsParentAlive,字节 bKeepReferenceToParent,字节 bCanCreateParent)
       在 MS.Internal.XcpImports.Measure_WithDesiredSizeNative(IntPtr 元素,Single inWidth,Single inHeight,Single& outWidth,Single& outHeight)
       在 MS.Internal.XcpImports.UIElement_Measure_WithDesiredSize(UIElement 元素,大小 availableSize)
       在 System.Windows.UIElement.Measure_WithDesiredSize(大小可用大小)
       在 System.Windows.Controls.VirtualizingStackPanel.MeasureChild(UIElement 孩子,大小 layoutSlotSize)
       在 System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(大小约束)
       在 System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget,双 inWidth,双 inHeight,Double& outWidth,Double& outHeight)
       在 MS.Internal.XcpImports.MeasureOverrideNative(IntPtr 元素,Single inWidth,Single inHeight,Single& outWidth,Single& outHeight)
       在 MS.Internal.XcpImports.FrameworkElement_MeasureOverride(FrameworkElement 元素,Size availableSize)
       在 System.Windows.FrameworkElement.MeasureOverride(大小可用大小)
       在 System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget,双 inWidth,双 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}}"/>
4

2 回答 2

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 明确包含对非托管资源的引用时,Microsoft 应考虑实施 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即使在出现异常的情况下也能正确清理原件。

于 2012-07-05T13:40:49.903 回答
2

每次被要求转换时,您已经在创建一个新MemoryStream的 - 尽管在这种情况下您不需要寻找。你不需要重置任何东西。

您应该真正找出引发了什么异常 - 这可能与内存不足无关。您已编辑问题以显示堆栈跟踪,但未显示引发的异常类型。一种可能性是它与在 WCF 服务中使用 WPF 控件有关,如果您的问题标签是可以通过的。

编辑:请注意,即使您不想处置MemoryStream,也确保BitmapImage在完成后处置结果。不幸的是,我们没有足够的背景来说明您正在做什么,因此无法在这方面提供任何建议。

于 2012-07-05T12:58:52.117 回答