我想顯示存儲在我的自定義圖庫中的Windows Phone 8照片文件夾中的所有圖像,該圖像使用ListBox
來顯示圖像。當我的ListBox中有圖像時,爲什麼會出現OutOfMemoryException?
的ListBox
代碼如下:
<phone:PhoneApplicationPage.Resources>
<MyApp:PreviewPictureConverter x:Key="PreviewPictureConverter" />
</phone:PhoneApplicationPage.Resources>
<ListBox Name="previewImageListbox" VirtualizingStackPanel.VirtualizationMode="Recycling">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel CleanUpVirtualizedItemEvent="VirtualizingStackPanel_CleanUpVirtualizedItemEvent_1">
</VirtualizingStackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Image Source="{Binding Converter={StaticResource PreviewPictureConverter}}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
用下面的轉換器:
public class PreviewPictureConverter : System.Windows.Data.IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
PreviewImageItem c = value as PreviewImageItem;
if (c == null)
return null;
return c.ImageData;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
圖像存儲在自定義類:
class PreviewImageItem
{
public Picture _picture = null;
public BitmapImage _bitmap = null;
public PreviewImageItem(Picture pic)
{
_picture = pic;
}
public BitmapImage ImageData
{
get
{
System.Diagnostics.Debug.WriteLine("Get picture " + _picture.ToString());
_bitmap = new BitmapImage();
Stream data = _picture.GetImage();
try
{
_bitmap.SetSource(data); // Out-of memory exception (see text)
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Exception : " + ex.ToString());
}
finally
{
data.Close();
data.Dispose();
data = null;
}
return _bitmap;
}
}
}
下面的代碼被用於設置ListBox
數據源:
private List<PreviewImageItem> _galleryImages = new List<PreviewImageItem>();
using (MediaLibrary library = new MediaLibrary())
{
PictureCollection galleryPics = library.Pictures;
foreach (Picture pic in galleryPics)
{
_galleryImages.Add(new PreviewImageItem(pic));
}
previewImageListbox.ItemsSource = _galleryImages;
};
最後這裏是「清理」代碼:
private void VirtualizingStackPanel_CleanUpVirtualizedItemEvent_1(object sender, CleanUpVirtualizedItemEventArgs e)
{
PreviewImageItem item = e.Value as PreviewImageItem;
if (item != null)
{
System.Diagnostics.Debug.WriteLine("Cleanup");
item._bitmap = null;
}
}
這一切工作正常,但代碼之後的幾個圖像與OutOfMemoryException
崩潰(滾動快尤其是當)。當滾動ListBox
時,方法VirtualizingStackPanel_CleanUpVirtualizedItemEvent_1
被稱爲regulary(例如,每2或3個列表框條目)。
這個示例代碼有什麼問題?
爲什麼內存不能釋放(速度不夠快)?
什麼是'圖片'和'GetImage()'方法做什麼?你只能將'_bitmap'字段設置爲'null',但是'_picture'字段是單獨存在的,它可能是保存一些數據的對象嗎?另外,公開公開領域並不是一個好習慣。在'PreviewImageItem'中實現'IDisposable'並在'VirtualizingStackPanel_CleanUpVirtualizedItemEvent_1'方法中調用'Dispose()'... – khellang
在清理過程中,您應該取消'_picture'屬性。 –
圖片的類型爲「Microsoft.Xna。 Framework.Media.Picture「並且不需要太多內存。大部分內存由BitmapImages使用,它們是由Picture對象提供的流創建的。 – Hyndrix