简体   繁体   中英

How to clear image cache in WindowsPhone 7. Setting UriSource to null does not work! What other variants to clear image cache in WP7?

Stefan Wick wrote in his blog that we can clear image cache in WP7 using code like

<code>
  BitmapImage bitmapImage = image.Source as BitmapImage;
  bitmapImage.UriSource = null;
  image.Source = null;

http://blogs.msdn.com/b/swick/archive/2012/04/05/10151249.aspx?CommentPosted=true#commentmessage

I have tested his example -- project (ImageTips.zip) --- and I can say that this code above does not work --- it does not release memory for cached images and does not delete cached images for your Application.

When you set UriSource to null -- you only releases memory on your page Caching.xaml, but if you will navigate back to MainPage.xaml --- you will see that memory does not released --- memory has increased !!!

To see that we can use Stefan's project --- ImageTips.zip in his blog...

Test project ImageTips.zip

To reproduce my observation --- you can: 1. Add code to MainPage.xaml for viewing current memory value like on your Caching.xaml page:

<tab>

        DispatcherTimer timer = new DispatcherTimer();
        timer.Interval = TimeSpan.FromMilliseconds(500);
        timer.Start();
        timer.Tick += delegate
        {
            GC.Collect();
            tbMemory.Text = string.Format("Memory: {0} bytes", DeviceExtendedProperties.GetValue("ApplicationCurrentMemoryUsage"));
        };
</code>
  1. Run your application. When we navigate to MainPage.xaml in first time --- value of memory equals nearly 9676448 bytes
  2. Click to navigate to Caching.xaml ( Image caching) --- value of memory equals nearly 9011200 bytes
  3. Click on button Show to show image -- value of memory equals nearly 12996608 bytes
  4. Click on Avoid Image Cache (to clear cached image) and after that press button clear --- 10090144 bytes.... So, where have dissapeared 413696 bytes??? (10090144 - 9676448 = 413696 bytes )
  5. Click on button back to navigate back to MainPage.xaml --- 11828248 bytes... But previous value before navigating to Caching.xaml was 9676448 bytes... So, where dissapeared 2151800 bytes????

    If you will navigate 20 times to page Caching.xaml (click show image and clear image with cache) and when navigate back to MainPage.xaml --- used memory will increase to 3.3 mb... and so on

I encountered with this problem in my Application and does not know how to resolve it.

What other variants to clear image cache in Windows phone 7? or why clearing image cache by setting UriSource to null --- does not work (does not release memory) when navigating back to previous page?

Thanks.

I can guarantee you that the example given in the blog works. Note that the amount of memory you are dealing with in the example is very small and it shouldn't matter if you have "lost" 2MBs here or there. It's probably because the GC hasn't kicked in, or in the meantime some other objects were allocated. (If you do in fact experience a severe leak then you have to check elsewhere in your code)

In my own application I am dealing with lots of images. At any given time they consume up to 60 MBs of memory. As such I was very paranoid not to have any memory leaks to pass certification.

The example in the blog assumes that you are programatically adding images, and that you have access to them, so you can set the source to null.

  BitmapImage bitmapImage = image.Source as BitmapImage;
  bitmapImage.UriSource = null;
  image.Source = null;

This alone should prevent image caching.

However, If you are using data binding you will quickly realize that preventing image caching may not be as easy.

In my application where I use data binding I have set up something similar to this:

Lets say you want to display images in a listbox.

//MainPage.xaml
<StackPanel>
<ListBox ItemsSource="{Binding Pictures}">
    <ListBox.ItemTemplate>
       <DataTemplate>
          <Image MaxHeight="1000" Source="{Source}" />
       </DataTemplate>
    </ListBox.ItemTeplate>
</ListBox> 
<Button Tap="LoadImages_Tap" Content="Load Images" />
</StackPanel> 

-

 //Picture.cs
    public class Picture
    { 
        private BitmapImage _source = new BitmapImage()
        {
            CreateOptions = BitmapCreateOptions.BackgroundCreation | BitmapCreateOptions.IgnoreImageCache | BitmapCreateOptions.DelayCreation
        };

        public Picture(string url) {
            _source.UriSource = new Uri(url, UriKind.Absolute);
        }

        public BitmapImage Source
        {
            get
            {
                return _source;
            } 
        } 

    }
}


//MainPage.xaml.cs
private ObservableCollection<Picture> _pictures = new ObservableCollection<Picture>();
public ObservableCollection<Picture> Pictures {
  get {
   return _pictures;
  }
}
public MainPage() {
  //...
  DataContext = this;
}

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
        if (e.NavigationMode == NavigationMode.Back)
        {
            PreventCaching();
            _pictures.Clear();
        }
        base.OnNavigatedFrom(e);
}  

private void PreventCaching() {
   foreach(var picture in _pictures) {
     picture.Source.UriSource = null;
   }
}
private void LoadPictures_Tap(object sender, EventArgs e) { 
     PreventCaching();
    _pictures.Clear();
    foreach(var url in SomeMethodThatReturnsUrlsForImages()) {  
      _pictures.Add(new Picture(url));
    }
}

The above should clear Image cache when you are using Data Binding (When there's no direct access to the <Image> element)

Alternatively you could probably create a custom attached dependency property, so you could do this: <Image ext:ImageExtension.Source="{SomeSource}" /> and handle the clearing of cache there but I didn't have a need for it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM