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は処理されませんでした
  Message = OutOfMemoryException
  スタックトレース:
       MS.Internal.FrameworkCallbacks.NotifyManagedDebuggerOnNativeOOM()で
       MS.Internal.XcpImports.BitmapSource_SetSourceNative(IntPtrビットストリームソース、CValue&byteStream)で
       MS.Internal.XcpImports.BitmapSource_SetSource(BitmapSourceビットストリームソース、CValue&byteStream)で
       System.Windows.Media.Imaging.BitmapSource.SetSourceInternal(Stream streamSource)で
       System.Windows.Media.Imaging.BitmapImage.SetSourceInternal(Stream streamSource)で
       System.Windows.Media.Imaging.BitmapSource.SetSource(Stream streamSource)で
       MeetPoint_B2C.ImageConverter.Convert(オブジェクト値、タイプtargetType、オブジェクトパラメータ、CultureInfoカルチャ)で
       System.Windows.Data.BindingExpression.ConvertToTarget(Object value)で
       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(Object sender、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、Boolean bIsNewParentAlive)で
       System.Windows.DependencyObject.UpdateTreeParent(IManagedPeer oldParent、IManagedPeer newParent、Boolean bIsNewParentAlive、Boolean keepReferenceToParent)で
       MS.Internal.FrameworkCallbacks.ManagedPeerTreeUpdate(IntPtr oldParentElement、IntPtr parentElement、IntPtr childElement、Byte bIsParentAlive、Byte bKeepReferenceToParent、Byte bCanCreateParent)で
       MS.Internal.XcpImports.Measure_WithDesiredSizeNative(IntPtr要素、シングルinWidth、シングルinHeight、シングル&outWidth、シングル&outHeight)で
       MS.Internal.XcpImports.UIElement_Measure_WithDesiredSize(UIElement element、Size availableSize)で
       System.Windows.UIElement.Measure_WithDesiredSize(Size availableSize)で
       System.Windows.Controls.VirtualizingStackPanel.MeasureChild(UIElement子、サイズlayoutSlotSize)で
       System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(サイズ制約)で
       System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget、Double inWidth、Double inHeight、Double&outWidth、Double&outHeight)で
       MS.Internal.XcpImports.MeasureOverrideNative(IntPtr要素、シングルinWidth、シングルinHeight、シングル&outWidth、シングル&outHeight)で
       MS.Internal.XcpImports.FrameworkElement_MeasureOverride(FrameworkElement element、Size availableSize)で
       System.Windows.FrameworkElement.MeasureOverride(Size availableSize)で
       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}}"/>
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ステートメントは使用できません。管理されていないリソースへの参照が明確に含まれている場合、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変換を求められるたびに、すでに新しいものを作成しています。ただし、この場合は探す必要はありません。何もリセットする必要はありません。

スローされている例外を正確に把握する必要があります。メモリ不足とは関係がない場合があります。質問を編集してスタックトレースを表示しましたが、スローされる例外のタイプは表示していません。1つの可能性は、質問タグに問題がある場合、WCFサービスでWPFコントロールを使用することと関係があることです。

編集:を破棄したくない場合でも、終了しMemoryStreamたら必ず結果を破棄する必要BitmapImageがあることに注意してください。残念ながら、私たちはあなたが何をしているのかについて、その面でアドバイスを与えるのに十分な文脈を持っていません。

于 2012-07-05T12:58:52.117 に答える