【问题标题】:Windows phone 8 Images inside LongListSelector memory leakLongListSelector内存泄漏中的Windows phone 8图像
【发布时间】:2014-07-01 09:34:13
【问题描述】:

我有一个 LongListSelector,其中包含一个图像控件,该控件可以从网络加载大量图像,这在一段时间内可以正常工作,但是在我加载了一些图像后,我会出现内存不足的异常。我读到其他人有同样的关于内存不足的问题,但仍然没有找到解决方案。我读过它与图像/位图图像缓存有关。

这是包含图像控件的 LongListSelector:

<phone:Pivot Title="MY APPLICATION">
        <!--Pivot item one-->
        <phone:PivotItem Header="Browse">
            <Grid>
                <phone:LongListSelector Name="llsGameList" ItemsSource="{Binding}" Tap="llsGameList_Tap" Margin="0,90,0,0">
                    <phone:LongListSelector.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                    <Image Name="imgGameList" Margin="0,10,0,10" Stretch="Fill" HorizontalAlignment="Left" VerticalAlignment="Top" Height="200" Width="150">
                                        <Image.Source>
                                            <BitmapImage UriSource="{Binding BoxArtFrontThumb}"
                                 CreateOptions="BackgroundCreation" DecodePixelHeight="200" DecodePixelWidth="150" />
                                        </Image.Source>
                                    </Image>
                            </Grid>
                        </DataTemplate>
                    </phone:LongListSelector.ItemTemplate>
                </phone:LongListSelector>
            </Grid>
        </phone:PivotItem>

在我的 MainPage.xaml.cs 中,我设置了 LongListSelector 的 DataContext:

llsGameList.DataContext = gd.GetGamesListItems;

这是我用来存储图像的类:

public class GetGamesList 
{
    public Uri BoxArtFrontThumb { get; set; }
}

这是包含所有图像的 ObservableCollection:

 private ObservableCollection<GetGamesList> _GetGamesListItems = new ObservableCollection<GetGamesList>();
    public ObservableCollection<GetGamesList> GetGamesListItems
    {
        get
        {
            return this._GetGamesListItems;
        }
    }

我希望我解释清楚。我真的希望有人可以帮助我解决这个内存问题。谢谢。

【问题讨论】:

  • 你可以试试这个:stackoverflow.com/a/17495047/869621
  • @KooKiz 方法能彻底解决图片内存缓存问题吗?
  • @KooKiz 哦,我看到你写道,它不能完全消除内存泄漏。有没有办法根本不泄漏任何内存?
  • 我不知道。但诀窍在于处理使用更多内存的内容:图片。控件本身使用的内存几乎可以忽略不计
  • 好的,谢谢。你能告诉我如何在我的代码中实现它,然后我会将你的答案标记为已接受:)。

标签: c# image windows-phone-8 memory-leaks longlistselector


【解决方案1】:

我不知道如何防止 LongListSelector 泄漏内存。不过,您可以使用一个小技巧来释放图片使用的内存。

首先,创建一个名为SafePicture 的新类,并使其继承自ContentControl。在里面,实现释放位图使用的内存的逻辑:

public class SafePicture : System.Windows.Controls.ContentControl
{
    public SafePicture()
    {
        this.Unloaded += this.SafePictureUnloaded;
    }

    private void SafePictureUnloaded(object sender, System.Windows.RoutedEventArgs e)
    {
        var image = this.Content as System.Windows.Controls.Image;

        if (image != null)
        {
            image.Source = null;
        }
    }
}

然后,使用此自定义控件包装所有图片:

<phone:Pivot Title="MY APPLICATION">
    <!--Pivot item one-->
    <phone:PivotItem Header="Browse">
        <Grid>
            <phone:LongListSelector Name="llsGameList" ItemsSource="{Binding}" Tap="llsGameList_Tap" Margin="0,90,0,0">
                <phone:LongListSelector.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <my:SafePicture>
                                <Image Name="imgGameList" Margin="0,10,0,10" Stretch="Fill" HorizontalAlignment="Left" VerticalAlignment="Top" Height="200" Width="150">
                                    <Image.Source>
                                        <BitmapImage UriSource="{Binding BoxArtFrontThumb}"
                             CreateOptions="BackgroundCreation" DecodePixelHeight="200" DecodePixelWidth="150" />
                                    </Image.Source>
                                </Image>
                            </my:SafePicture>
                        </Grid>
                    </DataTemplate>
                </phone:LongListSelector.ItemTemplate>
            </phone:LongListSelector>
        </Grid>
    </phone:PivotItem>

请注意,命名空间 my 是指您已将 SafePicture 放入的程序集,并且必须在页面顶部声明:

xmlns:my="clr-namespace:yourNamespace"

【讨论】:

  • 谢谢老兄:)。我很快就会对此进行测试。这个修复对你自己有用吗?当您在任何应用程序中使用它时?。
  • 好吧,我实现了代码,但是我应该如何调用代码?代码是自动调用的吗?
  • @Thunder 会自动调用。如果您有疑问,可以在SafePictureUnloaded 方法中设置断点。是的,我在我的应用程序中使用它,这是我发现处理这些内存泄漏的唯一可靠方法
  • 好的,再次感谢。我现在对其进行了测试,我认为它正在减少内存使用量:)。但是每次内存都会增加一点,是不是 LongListSelector 中的一个错误导致了这种情况发生?如果我使用列表框控件,你认为它会更好吗?。
  • 你不会有列表框的泄漏,但你也不会有虚拟化,这将是显示大量图片的一个大问题。 Telerik 控件限时免费,请抓紧机会:telerik.com/account/teched.aspx 他们的 RadDataBoundListBox 支持虚拟化并且不会泄漏内存
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-23
  • 1970-01-01
  • 1970-01-01
  • 2012-03-21
  • 2014-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多