मैं अपनी कस्टम गैलरी में विंडोज फोन 8 फोटो फ़ोल्डर में संग्रहीत सभी छवियों को प्रदर्शित करना चाहता हूं जो छवियों को प्रदर्शित करने के लिए 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
कोड इस प्रकार है ListBox
डेटा स्रोत सेट करने के लिए:
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
साथ दुर्घटनाओं (खासकर जब तेजी से स्क्रॉल):
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;
};
अंत में यहाँ "सफाई" कोड है। विधि VirtualizingStackPanel_CleanUpVirtualizedItemEvent_1
को विनियामक कहा जाता है (उदा। प्रत्येक 2 या 3 सूची बॉक्स प्रविष्टियां) जब ListBox
स्क्रॉल किया जाता है।
इस नमूना कोड के साथ क्या गलत है?
स्मृति क्यों मुक्त नहीं है (पर्याप्त तेज़)?
'चित्र 'क्या है और' GetImage() 'विधि क्या करती है? आपने केवल '_bitmap' फ़ील्ड को' शून्य 'पर सेट किया है, लेकिन' _ चित्र 'फ़ील्ड अकेला छोड़ा गया है, क्या यह वह ऑब्जेक्ट हो सकता है जिसमें कुछ डेटा हो? साथ ही, सार्वजनिक रूप से फ़ील्ड का पर्दाफाश करना एक अच्छा अभ्यास नहीं है। 'PreviewImageItem' में' IDISposable' लागू करें और अपने 'VirtualizingStackPanel_CleanUpVirtualizedItemEvent_1' विधि में 'निपटान()' को कॉल करें ... – khellang
सफाई में, आपको' _ चित्र 'संपत्ति को –
चित्र को समाप्त करना चाहिए "चित्र। माइक्रोसॉफ्ट.एक्सना। फ्रेमवर्क। मीडिया। चित्र "और अधिक स्मृति की आवश्यकता नहीं है। अधिकांश स्मृति का उपयोग बिटमैप इमेज द्वारा किया जाता है जो चित्र वस्तुओं द्वारा प्रदान की गई धाराओं से बनाए जाते हैं। – Hyndrix