什么在Silverlight 4应用程序中缓存图像数据? [英] What is caching the image data in my Silverlight 4 application?

查看:57
本文介绍了什么在Silverlight 4应用程序中缓存图像数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Silverlight应用程序中出现了某些问题.这是一个问题,因为这是一个目录应用程序,其中包含许多用户可以浏览的图像.如果用户浏览提供的每个库,则应用程序将耗尽内存并崩溃.我知道这是图像的问题,因为如果我禁用图像,私有工作集将永远不会超过170 MB.我有一个用户控件(DownloadImage),它在下载图像时显示进度条.这是 my 代码中唯一引用BitmapImage对象的东西.我运行了探查器( ANTS Memory Profiler 7.0 - -好产品,只给他们道具),则表明所有BitmapImage实例均已正确收集.与DownloadImage控件的所有实例一样.

Something is holding on to the images in my Silverlight application. This is a problem because this is a catalog application with a lot of images that the user can browse through. If the user browses through every library provided the application will run out of memory and crash. I know it is a problem with images because if I disable images the private working set never exceeds 170 MB. I have a user control (DownloadImage) that shows a progress bar while the image is downloading. It is the only thing in my code that is referencing the BitmapImage objects. I ran a profiler (ANTS Memory Profiler 7.0 -- good product, just giving them props) and it showed that all of the BitmapImage instances are being properly collected. As are all instances of DownloadImage controls.

这是DownloadImage背后的代码:

    public partial class DownloadImage : UserControl
    {
        public static readonly DependencyProperty SourceProperty = DependencyProperty.RegisterAttached("Source", typeof(Uri), typeof(DownloadImage), new PropertyMetadata(null, OnSourcePropertyChanged));

        /// <summary>
        /// Default C'tor
        /// </summary>
        public DownloadImage()
        {
            InitializeComponent();
        }

        /// <summary>
        /// D'tor
        /// </summary>
        ~DownloadImage()
        {
        }

        /// <summary>
        /// Source - Image source.
        /// </summary>
        public Uri Source
        {
            get { return (Uri)GetValue(SourceProperty); }
            set { SetValue(SourceProperty, value); }
        }

        /// <summary>
        /// Initialize this DownloadImage with the given <see cref="BitmapImage"/> (<paramref name="a_bitmapImage"/>).
        /// </summary>
        /// <param name="a_bitmapImage">Given <see cref="BitmapImage"/>.</param>
        public void Create(BitmapImage a_bitmapImage)
        {
            _noImage.Visibility = Visibility.Collapsed;

            _image.Source = a_bitmapImage;
        }

        /// <summary>
        /// Initialize this DownloadImage with the given image source <see cref="Uri"/> (<paramref name="a_imageSource"/>).
        /// </summary>
        /// <param name="a_imageSource">Given image source <see cref="Uri"/>.</param>
        public void Create(Uri a_imageSource)
        {
            _noImage.Visibility = Visibility.Collapsed;

            BitmapImage bitmapImage = new BitmapImage();
            bitmapImage.CreateOptions = BitmapCreateOptions.DelayCreation | BitmapCreateOptions.IgnoreImageCache;
            bitmapImage.DownloadProgress += new EventHandler<DownloadProgressEventArgs>(OnDownloadProgress);
            bitmapImage.ImageOpened += new EventHandler<RoutedEventArgs>(OnDownloadSuccess);
            bitmapImage.ImageFailed += new EventHandler<ExceptionRoutedEventArgs>(OnDownloadFailed);
            bitmapImage.UriSource = a_imageSource;

            _image.Source = bitmapImage;
        }

        /// <summary>
        /// When the download progress changes.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void OnDownloadProgress(object sender, DownloadProgressEventArgs e)
        {
            _progress.Visibility = Visibility.Visible;
            _progress.Value = e.Progress;
        }

        /// <summary>
        /// When the download succeeds.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void OnDownloadSuccess(object sender, RoutedEventArgs e)
        {
            _noImage.Visibility = Visibility.Collapsed;
            _progress.Visibility = Visibility.Collapsed;
        }

        /// <summary>
        /// When the download fails.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void OnDownloadFailed(object sender, ExceptionRoutedEventArgs e)
        {
            _noImage.Visibility = Visibility.Visible;
            _progress.Visibility = Visibility.Collapsed;
        }

        /// <summary>
        /// When SourceProperty dependency property changes.
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="e"></param>
        private static void OnSourcePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            DownloadImage downloadImage = obj as DownloadImage;
            if (downloadImage != null)
            {
                if (e.NewValue is Uri)
                    downloadImage.Create(e.NewValue as Uri);
                else if (e.NewValue is BitmapImage)
                    downloadImage.Create(e.NewValue as BitmapImage);
                else
                    return;
            }
        }

    }

这是XAML:

<UserControl x:Name="userControl" x:Class="{Intentionally Left Blank}.DownloadImage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:helpers="clr-namespace:{Intentionally Left Blank}.Helpers"
             xmlns:res="clr-namespace:{Intentionally Left Blank}.Resources"
             xmlns:ee="http://schemas.microsoft.com/expression/2010/effects"
             mc:Ignorable="d"
             d:DesignHeight="100" d:DesignWidth="100" Background="{StaticResource ImageBackground}">
    <Grid x:Name="LayoutRoot" Background="{Binding Background, ElementName=userControl}">
        <Viewbox HorizontalAlignment="Center" VerticalAlignment="Center" Margin="8">
            <TextBlock x:Name="_noImage" TextWrapping="Wrap" FontSize="16"
                res:Strings.Assignment="Text=DownloadImage.NoImage" Height="23" Width="79" Visibility="Collapsed">
                <TextBlock.Foreground>
                    <SolidColorBrush Color="{StaticResource GrayLetters}"/>
                </TextBlock.Foreground>
            </TextBlock>
        </Viewbox>
        <Image x:Name="_image"/>
        <ProgressBar x:Name="_progress" Height="15" VerticalAlignment="Bottom" Margin="1" Visibility="Collapsed"/>
    </Grid>
</UserControl>

推荐答案

我不确定为什么它起作用,但是我在DownloadImage中添加了以下代码,并且内存稳定.

I'm not sure why it worked, but I added the following code to DownloadImage and memory is stable.

    /// <summary>
    /// Default C'tor
    /// </summary>
    public DownloadImage()
    {
        InitializeComponent();

        Unloaded += new RoutedEventHandler(OnUnloaded);
    }

    /// <summary>
    /// When the control is unloaded.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void OnUnloaded(object sender, RoutedEventArgs e)
    {
        BitmapImage bitmapImage = _image.Source as BitmapImage;
        if (bitmapImage != null)
        {
            bitmapImage.DownloadProgress -= new EventHandler<DownloadProgressEventArgs>(OnDownloadProgress);
            bitmapImage.ImageOpened -= new EventHandler<RoutedEventArgs>(OnDownloadSuccess);
            bitmapImage.ImageFailed -= new EventHandler<ExceptionRoutedEventArgs>(OnDownloadFailed);
        }

        _image.Source = null;
    }

这篇关于什么在Silverlight 4应用程序中缓存图像数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆