什么在我的Silverlight 4应用程序中缓存图像数据?

什么在我的Silverlight 4应用程序中缓存图像数据?,silverlight,image,memory,Silverlight,Image,Memory,我的Silverlight应用程序中的图像存在一些问题。这是一个问题,因为这是一个目录应用程序,用户可以浏览大量图像。如果用户浏览提供的每个库,应用程序将耗尽内存并崩溃。我知道这是图像的问题,因为如果我禁用图像,私有工作集永远不会超过170MB。我有一个用户控件(DownloadImage),在图像下载时显示进度条。这是我的代码中唯一引用BitmapImage对象的东西。我运行了一个探查器(这是一个很好的产品,只是给了他们一些道具),它显示所有的BitmapImage实例都被正确收集。所有Dow

我的Silverlight应用程序中的图像存在一些问题。这是一个问题,因为这是一个目录应用程序,用户可以浏览大量图像。如果用户浏览提供的每个库,应用程序将耗尽内存并崩溃。我知道这是图像的问题,因为如果我禁用图像,私有工作集永远不会超过170MB。我有一个用户控件(
DownloadImage
),在图像下载时显示进度条。这是我的代码中唯一引用
BitmapImage
对象的东西。我运行了一个探查器(这是一个很好的产品,只是给了他们一些道具),它显示所有的
BitmapImage
实例都被正确收集。所有
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;
            }
        }

    }
public部分类下载image:UserControl
{
public static readonly dependencProperty SourceProperty=dependencProperty.RegisterAttached(“Source”,typeof(Uri),typeof(DownloadImage),new PropertyMetadata(null,OnSourcePropertyChanged));
/// 
///默认C'tor
/// 
公众下载图片()
{
初始化组件();
}
/// 
///德托
/// 
~DownloadImage()
{
}
/// 
///源-图像源。
/// 
公共Uri源
{
获取{return(Uri)GetValue(SourceProperty);}
set{SetValue(SourceProperty,value);}
}
/// 
///使用给定的()初始化此下载映像。
/// 
///给定的。
公共无效创建(位图图像a_位图图像)
{
_noImage.Visibility=Visibility.collazed;
_image.Source=一个位图图像;
}
/// 
///使用给定的映像源()初始化此下载映像。
/// 
///给定图像源。
公共void创建(Uri a_imageSource)
{
_noImage.Visibility=Visibility.collazed;
BitmapImage BitmapImage=新的BitmapImage();
bitmapImage.CreateOptions=BitmapCreateOptions.DelayCreation | BitmapCreateOptions.IgnoreImageCache;
bitmapImage.DownloadProgress+=新事件处理程序(OnDownloadProgress);
bitmapImage.ImageOpened+=新事件处理程序(OnDownloadSuccess);
bitmapImage.ImageFailed+=新事件处理程序(OnDownloadFailed);
bitmapImage.UriSource=图像源;
_image.Source=位图图像;
}
/// 
///当下载进度发生变化时。
/// 
/// 
/// 
受保护的虚拟void OnDownloadProgress(对象发送方,DownloadProgressEventArgs e)
{
_progress.Visibility=可见性.Visibility;
_进步。价值=进步;
}
/// 
///当下载成功时。
/// 
/// 
/// 
受保护的虚拟void OnDownloadSuccess(对象发送方,RoutedEventArgs e)
{
_noImage.Visibility=Visibility.collazed;
_progress.Visibility=Visibility.Collapsed;
}
/// 
///当下载失败时。
/// 
/// 
/// 
受保护的虚拟void OnDownloadFailed(对象发送方,例外RoutedEventargs e)
{
_noImage.Visibility=可见性.Visibility;
_progress.Visibility=Visibility.Collapsed;
}
/// 
///当SourceProperty依赖项属性更改时。
/// 
/// 
/// 
SourcePropertyChanged上的私有静态无效(DependencyObject对象,DependencyPropertyChangedEventArgs e)
{
DownloadImage DownloadImage=obj作为DownloadImage;
if(downloadImage!=null)
{
if(例如,NewValue是Uri)
downloadImage.Create(例如,NewValue作为Uri);
else if(例如,NewValue为BitmapImage)
下载图像。创建(例如,作为位图图像的NewValue);
其他的
返回;
}
}
}
下面是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>

我不确定它为什么会工作,但我在
下载图像中添加了以下代码,并且内存是稳定的

    /// <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;
    }
//
///默认C'tor
/// 
公众下载图片()
{
初始化组件();
已卸载+=新路由EventHandler(未加载);
}
/// 
///卸载控件时。
/// 
/// 
/// 
私有void OnUnloaded(对象发送方,RoutedEventArgs e)
{
BitmapImage BitmapImage=\u image.Source作为BitmapImage;
如果(bitmapImage!=null)
{
bitmapImage.DownloadProgress-=新事件处理程序(OnDownloadProgress);
bitmapImage.ImageOpen-=新事件处理程序(OnDownloadSuccess);
bitmapImage.ImageFailed-=新事件处理程序(OnDownloadFailed);
}
_image.Source=null;
}

我不确定它为什么会工作,但我在
下载图像中添加了以下代码,并且内存是稳定的

    /// <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;
    }
//
///默认C'tor
/// 
公众下载图片()
{
初始化组件();
已卸载+=新路由EventHandler(未加载);
}
/// 
///卸载控件时。
/// 
/// 
/// 
私有void OnUnloaded(对象发送方,RoutedEventArgs e)
{
BitmapImage BitmapImage=\u image.Source作为BitmapImage;
如果(bitmapImage!=null)
{
bitmapImage.DownloadProgress-=新事件处理程序(OnDownloadProgress);
bitmapImage.ImageOpen-=新事件处理程序(OnDownloadSuccess);
位图图像