8

In my application I am using the below mentioned helper method for binding my Isolated storage image to Image control. I got this helper method from the link "Binding Image stored in the Isolated Storage to Image Control in 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);
                }
            }
        });               
    }
}

}

I am using this inside a ListBox control. And if try with default library images everything will work as expected. But if I try with the images with large size( taken through device camera ) the app crashes.

And here is the exception what I am getting

An exception of type 'System.OutOfMemoryException' occurred in System.Windows.ni.dll but was not handled in user code

stack trace

at MS.Internal.FrameworkCallbacks.NotifyManagedDebuggerOnNativeOOM() 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 MyaPP.Common.IsoStoreImageSource.<>c__DisplayClass4.<>c__DisplayClass6.b__1(Object _)

Community
  • 1
  • 1
Nitha Paul
  • 1,401
  • 1
  • 14
  • 30
  • How many images are you in your list view? How big are they? Can you run memory analysis on your app (`Debug -> Start Windows Phone Application Analysis -> Profiling -> Memory` in Visual Studio) and post your results? – Haspemulator Apr 22 '13 at 17:55
  • Try to use LongListSelector as Flat List – Shashi Apr 23 '13 at 07:37
  • 2
    @Haspemulator : The issue is mentioned here "http://stackoverflow.com/questions/15700340/out-of-memory-exception-while-loading-images-from-isolated-storage", "http://blogs.developpeur.org/kookiz/archive/2013/02/17/wpdev-memory-leak-with-bitmapimage.aspx", How I can resolve this issue with your implementation. – Nitha Paul Apr 23 '13 at 11:51
  • I am also facing the same issue. @Haspemulator , I perform memory profiling and got a similar response mentioned in the above blog. Can you please update a solution to this issue. – StezPet Apr 23 '13 at 11:55

3 Answers3

0

The caching within the ListBox might be taking up your memory and this is especially noticeable with larger images. I'm not familiar with the helper method you've posted but try adding this.

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

    //rest of the code ...
}
keyboardP
  • 68,824
  • 13
  • 156
  • 205
0

Okay, it took some time for me to return to this issue. I'll share my findings here, but I'm not considering them a real answer to the issue, but rather a workaround. However, I hope it will help somebody.

First I want to confirm OutOfMemoryException happens in certain circumstances. But, surprisingly, it depends on the page layout you're using. In fact, if your layout involves StackPanel, you'll have an exception. I guess, it comes down to the fact how MeasureOverride and ArrangeOverride methods are implemented in StackPanel (though I may be completely wrong here). It looks like when ListBox is a child to StackPanel, it tries to load all of the images before display. This, of course, causes the memory leak.

On the other hand, if you use something like Grid as a parent for list of images, then there's no such exceptions, and the memory load is reasonable.

Here's page layout that worked for me:

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

This is the best answer I have for you now. Please let me know if it helped.

Haspemulator
  • 11,050
  • 9
  • 49
  • 76
0

You can try like this, Stream object will automatically disposed.

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;
         }
     }
}
gofor.net
  • 4,218
  • 10
  • 43
  • 65