8

私のアプリケーションでは、以下のヘルパー メソッドを使用して、Isolated ストレージ イメージを Image コントロールにバインドしています。このヘルパー メソッドは、リンク「分離ストレージに保存されているイメージを Windows Phone のイメージ コントロールにバインドする」から取得しました。

public class IsoStoreImageSource : DependencyObject
{
public static void SetIsoStoreFileName(UIElement element, string value)
{
    element.SetValue(IsoStoreFileNameProperty, value);
}
public static string GetIsoStoreFileName(UIElement element)
{
    return (string)element.GetValue(IsoStoreFileNameProperty);
}

// Using a DependencyProperty as the backing store for IsoStoreFileName.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsoStoreFileNameProperty =
    DependencyProperty.RegisterAttached("IsoStoreFileName", typeof(string), typeof(IsoStoreImageSource), new PropertyMetadata("", Changed));

private static void Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    Image img = d as Image;

    if (img != null)
    {
        var path = e.NewValue as string;
        SynchronizationContext uiThread = SynchronizationContext.Current;

        Task.Factory.StartNew(() =>
        {
            using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (isoStore.FileExists(path))
                {
                    var stream = isoStore.OpenFile(path, System.IO.FileMode.Open, FileAccess.Read);
                    uiThread.Post(_ =>
                    {
                        var _img = new BitmapImage();
                        _img.SetSource(stream);
                        img.Source = _img;
                    }, null);
                }
            }
        });               
    }
}

}

これを ListBox コントロール内で使用しています。デフォルトのライブラリ イメージを試してみると、すべてが期待どおりに機能します。しかし、大きなサイズの画像(デバイスのカメラで撮影したもの)を試してみると、アプリがクラッシュします。

そして、ここに私が得ている例外があります

タイプ 'System.OutOfMemoryException' の例外が System.Windows.ni.dll で発生しましたが、ユーザー コードで処理されませんでした

スタックトレース

MS.Internal.FrameworkCallbacks.NotifyManagedDebuggerOnNativeOOM() で MS.Internal.XcpImports.BitmapSource_SetSource(BitmapSource bitmapSource, CValue& byteStream) で System.Windows.Media.Imaging.BitmapSource.SetSourceInternal(ストリーム streamSource) で System.Windows.Media.Imaging. MyaPP.Common.IsoStoreImageSource.<>c__DisplayClass4.<>c__DisplayClass6.b__1(Object _) の System.Windows.Media.Imaging.BitmapSource.SetSource(ストリーム streamSource) の BitmapImage.SetSourceInternal(ストリーム streamSource)

4

3 に答える 3

0

内のキャッシュがListBoxメモリを消費している可能性があり、これは大きな画像で特に顕著です。あなたが投稿したヘルパー メソッドには詳しくありませんが、これを追加してみてください。

if (img != null)
{
    BitmapImage bitmapImage = img.Source as BitmapImage;
    bitmapImage.UriSource = null;
    img.Source = null;

    //rest of the code ...
}
于 2013-04-22T12:50:51.903 に答える
0

さて、この問題に戻るまでに時間がかかりました。ここで調査結果を共有しますが、問題に対する本当の答えではなく、回避策であると考えています。しかし、それが誰かを助けることを願っています。

OutOfMemoryExceptionまず、特定の状況で発生することを確認したいと思います。しかし、驚くべきことに、使用しているページ レイアウトによって異なります。実際、レイアウトに が含まれStackPanelている場合は、例外があります。私は、それはメソッドがどのように実装されMeasureOverrideているかという事実に帰着すると思います(ただし、ここでは完全に間違っているかもしれません)。の子のように見えますが、表示する前にすべての画像を読み込もうとします。もちろん、これはメモリリークを引き起こします。ArrangeOverrideStackPanelListBoxStackPanel

一方、Grid画像のリストの親としてのようなものを使用する場合、そのような例外はなく、メモリ負荷は妥当です.

これが私のために働いたページレイアウトです:

<Grid>
    <ListBox ItemsSource="{Binding IsoStorePics}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Image local:IsoStoreImageSource.IsoStoreFileName="{Binding Path}" Margin="5"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

これが私が今あなたに持っている最良の答えです。それが役に立ったかどうか教えてください。

于 2013-04-23T16:11:52.353 に答える
0

このように試すことができます.Streamオブジェクトは自動的に破棄されます.

using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication())
{                               
     if (iso.FileExists(imagePath))
     {
         using (Stream imagestream = new IsolatedStorageFileStream(imagePath, FileMode.Open, FileAccess.Read, FileShare.Read, iso))
         {
               BitmapImage bmp = new BitmapImage();
               bmp.SetSource(imagestream);
               imgControl.Source = bmp;
         }
     }
}
于 2014-08-05T06:59:22.797 に答える