Как освободить память, занимаемую изображениями в шаблоне данных в приложении Windows Phone 8?

У меня есть longlistselector, для которого у меня есть шаблон данных, который определяет тип элементов, которые будут добавлены в список. Шаблон данных имеет элемент управления Image, источник которого динамически связан с путем, поэтому каждый элемент в списке имеет связанный элемент управления Image. Проблема, с которой я сталкиваюсь, заключается в том, что эти средства управления изображениями никогда не освобождают память, которую они занимают, что приводит к исключению нехватки памяти. В обычном сценарии я устанавливаю bitmapImage.UriSource=null, чтобы освободить память, связанную с растровым изображением, но не могу найти способ сделать это в этом сценарии. Вот код xaml для longlistselector и связанный с ним шаблон данных.

Шаблон данных

<phone:PhoneApplicationPage.Resources>
    <DataTemplate x:Key="MediaItemTemplate">      
        <Canvas VerticalAlignment="Top">
            <Border BorderBrush="#FF4791CA" BorderThickness="3">
                <Image Height="100" Width="100" VerticalAlignment="Top" Grid.RowSpan="2" Stretch="UniformToFill">
                    <Image.Source> 
                          <BitmapImage UriSource="{Binding path}" CreateOptions="BackgroundCreation"  DecodePixelHeight="50" DecodePixelWidth="50"/>
                    </Image.Source>
                </Image>
             </Border>
             <Image Source="/Icons/check.png" Height="16" Width="16" Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" Margin="80,7,7,0" Canvas.ZIndex="100" OpacityMask="Black" Visibility="{Binding visibility}" Name="checkImage" >    
             </Image>
          </Canvas> 
      </DataTemplate>
</phone:PhoneApplicationPage.Resources>

LonglistSelector

<phone:LongListSelector 
            Tap="ListMedia_Tap"
            x:Name="ListMedia"
            HorizontalAlignment="Left"
            Height="624" 
            VerticalAlignment="Top"
            Width="436"

Background = "Transparent"

ItemTemplate = "{StaticResource MediaItemTemplate}" LayoutMode = "Grid" GridCellSize = "120,120" />

Я очень новичок в программировании Windows Phone. В основном я хочу развить опыт работы с изображениями в браузере. Пожалуйста, помогите мне с способами освободить память. В случае, если я делаю это совершенно неправильно, пожалуйста, исправьте меня или предложите лучшие способы достижения той же функциональности. Спасибо заранее...

3 ответа

Решение, которое я нашел для обработки этого случая, заключается в создании пользовательского элемента управления, чтобы автоматически установить для Urisource значение NULL:

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;
        }
    }
}

Затем просто оберните все ваши изображения в этот элемент управления:

<my:SafePicture>
    <Image Source="{Binding Path=path}" />
</my:SafePicture>

При прокрутке с вашим кодом (без использования Loaded) изображения теряются после прокрутки вниз и возврата в верхнюю часть списка (скорость не имеет значения). При использовании Loaded прокрутка wokrs в порядке: можно прокрутить вниз и вернуться наверх (отладчик показывает, что вызываются Unloaded и Loaded), и изображения там. Однако при переходе на другую страницу (у меня есть страницы с основными данными), они перепутаны.

По умолчанию Windows Phone хранит сообщения, загруженные из Uri, в памяти, чтобы избежать необходимости загружать их снова. (Это грубая форма кеширования.)

Чтобы освободить память, используемую этими изображениями, вам необходимо явно освободить все ссылки на них. Посмотрите MSDN: Подсказки Изображения для Windows Phone 7 для получения дополнительной информации

Другие вопросы по тегам