什么在Silverlight 4应用程序中缓存图像数据? [英] What is caching the image data in my Silverlight 4 application?
问题描述
我的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屋!