Note that there are some explanatory texts on larger screens.

plurals
  1. POImageTools AnimatedImage not releasing memory
    text
    copied!<p>I have a WindowsPhone 7.8 application, that needs to display animated GIFs as well as images that are supported directly by Silverlight. Therefor we created a custom user control <code>public sealed partial class ExtendedImageControl : UserControl, IDisposable</code>, which has a DependancyProperty called ImageSource. This property is bound to a URL. The code behind will then either insert a regular Image control into the LayoutRoot, or a AnimatedImage. However, the AnimatedImage will not release its memory when it gets out of view or the containing page is closed.</p> <p>The loading logic is the following:</p> <pre><code>ExtendedImage loadedImage = (ExtendedImage)await Utils.Caching.Image.LoadCachedImageFromUrlAsync&lt;ExtendedImage&gt;(loadedLocation); if (ImageSource == loadedLocation) { AnimatedImage image = new AnimatedImage(); image.Stretch = stretch; image.Source = loadedImage; LayoutRoot.Children.Add(image); CurrentImageMode = ExtendedImageMode.AnimatedImage; loadedImage = null; #if DEBUG App.logger.log("Loaded {0} as animated image", loadedLocation); #endif imageDisplay = image; raiseImageUpdated(); } </code></pre> <p>Ultimately, the image is loaded with</p> <pre><code> WebClient client = new WebClient(); ExtendedImage image = new ExtendedImage(); using (Stream source = await client.OpenReadTaskAsync(location)) { if (location.ToString().EndsWith("gif", StringComparison.InvariantCultureIgnoreCase)) { image.SetSource(source); TaskCompletionSource&lt;ExtendedImage&gt; imageLoaded = new TaskCompletionSource&lt;ExtendedImage&gt;(); EventHandler loadingCompleteHandler = new EventHandler((sender, e) =&gt; { imageLoaded.SetResult(image); }); EventHandler&lt;UnhandledExceptionEventArgs&gt; loadingFailedHandler = new EventHandler&lt;UnhandledExceptionEventArgs&gt;((sender, e) =&gt; { imageLoaded.SetResult(image); #if DEBUG if (System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break(); #endif }); image.LoadingCompleted += loadingCompleteHandler; image.LoadingFailed += loadingFailedHandler; image = await imageLoaded.Task; //Remove handlers, otherwise the object might be kept in the memory image.LoadingCompleted -= loadingCompleteHandler; image.LoadingFailed -= loadingFailedHandler; } else { //... load with native Silverlight methods } } return image; </code></pre> <p>We noticed the memory problem very early on, so the control implements the IDisposable interface with</p> <pre><code> public void Dispose() { unloadImage(); GC.SuppressFinalize(this); } private void unloadImage() { SmartDispatcher.BeginInvoke(() =&gt; { if (imageDisplay != null) { if (imageDisplay is AnimatedImage) { if ((imageDisplay as AnimatedImage).Source != null &amp; (imageDisplay as AnimatedImage).Source.Frames != null) (imageDisplay as AnimatedImage).Source.Frames.Clear(); (imageDisplay as AnimatedImage).Stop(); (imageDisplay as AnimatedImage).Source = null; } else if (imageDisplay is Image &amp;&amp; ((Image)imageDisplay).Source != GIFplaceholder) { (imageDisplay as Image).Source = null; } imageDisplay = null; } }); } </code></pre> <p>However, the Dispose method is never called on the image.</p> <p>What can I do to find out why this object isn't picked up by the GC? I'm not registering any eventhandlers so as far as I understand, it should be collected when the Application page is navigated away from. I tried adding a destructor as well, however this one is not called as well.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload