2011-05-18 57 views
1

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

这里是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> 
+0

你有没有读过Jeff Prosise的博客条目Silverlight的大图像问题(以及你能做些什么)? http://www.wintellect.com/CS/blogs/jprosise/archive/2009/12/17/silverlight-s-big-image-problem-and-what-you-can-do-about-it.aspx – 3264 2011-05-18 15:33:55

+0

太棒了,这可能会奏效。但是'Stream'从哪里来? – Jordan 2011-05-18 15:58:48

+0

我做了类似的事情。我在我的服务器上创建了一个ASPX实例来返回thumnail大小的图像(100 x 100像素)。这是更好,但我不满意。这个图像数据是我的应用程序额外的重量。没有办法控制保存这些图像数据的方法吗? – Jordan 2011-05-19 15:01:47

回答

1

我不知道为什么它的工作,但我下面的代码添加到DownloadImage和内存稳定。

/// <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; 
    } 
相关问题