2013-04-22 12 views
8

W mojej aplikacji używam poniższej metody pomocniczej do wiązania mojego izolowanego obrazu do sterowania obrazem. Mam tej metody pomocnika z linku „Binding Image stored in the Isolated Storage to Image Control in Windows PhoneAplikacja ulega awarii podczas próby związania izolowanego obrazu pamięci

public class IsoStoreImageSource : DependencyObject 
{ 
public static void SetIsoStoreFileName(UIElement element, string value) 
{ 
    element.SetValue(IsoStoreFileNameProperty, value); 
} 
public static string GetIsoStoreFileName(UIElement element) 
{ 
    return (string)element.GetValue(IsoStoreFileNameProperty); 
} 

// Using a DependencyProperty as the backing store for IsoStoreFileName. This enables animation, styling, binding, etc... 
public static readonly DependencyProperty IsoStoreFileNameProperty = 
    DependencyProperty.RegisterAttached("IsoStoreFileName", typeof(string), typeof(IsoStoreImageSource), new PropertyMetadata("", Changed)); 

private static void Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    Image img = d as Image; 

    if (img != null) 
    { 
     var path = e.NewValue as string; 
     SynchronizationContext uiThread = SynchronizationContext.Current; 

     Task.Factory.StartNew(() => 
     { 
      using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication()) 
      { 
       if (isoStore.FileExists(path)) 
       { 
        var stream = isoStore.OpenFile(path, System.IO.FileMode.Open, FileAccess.Read); 
        uiThread.Post(_ => 
        { 
         var _img = new BitmapImage(); 
         _img.SetSource(stream); 
         img.Source = _img; 
        }, null); 
       } 
      } 
     });    
    } 
} 

}

Używam tego wewnątrz formantu ListBox. A jeśli spróbujesz z domyślnymi obrazami biblioteki wszystko będzie działać zgodnie z oczekiwaniami. Ale jeśli spróbuję z obrazami o dużym rozmiarze (zrobionym aparatem urządzenia), aplikacja się zawiesza.

I tu jest wyjątek co ja dostaję

wyjątek typu „System.OutOfMemoryException” wystąpiło w System.Windows.ni.dll ale nie było obsługiwane w kodzie użytkownika

ślad stosu

w MS.Internal.FrameworkCallbacks.NotifyManagedDebuggerOnNativeOOM() w MS.Internal.XcpImports.BitmapSource_SetSource (BitmapSource BitmapSource, CValue & byteStream) w System.Windows.Media.Imaging.BitmapSource.SetSourceInternal strumieni (strumień ource) w System.Windows.Media.Imaging.BitmapImage.SetSourceInternal (Stream streamSource) w System.Windows.Media.Imaging.BitmapSource.SetSource (Stream streamSource) w MyaPP.Common.IsoStoreImageSource. <> c__DisplayClass4. <> c__DisplayClass6.b__1 (Obiekt _)

+0

Ile zdjęć posiadasz w widoku listy? Jak duże są?Czy możesz uruchomić analizę pamięci w swojej aplikacji ('Debugowanie -> Uruchom aplikację Windows Phone Application Analysis -> Profilowanie -> Pamięć' w Visual Studio) i zamieścić swoje wyniki? – Haspemulator

+0

Spróbuj użyć LongListSelector jako płaskiej listy – Mahantesh

+2

@ Haspemulator: Problem jest tutaj mowa "http://stackoverflow.com/questions/15700340/out-of-memory-exception-while-loading-images-from-isolated- storage" , "http://blogs.developpeur.org/kookiz/archive/2013/02/17/wpdev-memory-leak-with-bitmapimage.aspx", Jak mogę rozwiązać ten problem z twoją implementacją. –

Odpowiedz

0

Pamięć podręczna w ramach ListBox może zajmować Twoją pamięć i jest to szczególnie widoczne w przypadku większych obrazów. Nie znam wprowadzonej przez Ciebie metody pomocy, ale spróbuj ją dodać.

if (img != null) 
{ 
    BitmapImage bitmapImage = img.Source as BitmapImage; 
    bitmapImage.UriSource = null; 
    img.Source = null; 

    //rest of the code ... 
} 
0

Okej, zajęło mi trochę czasu, aby powrócić do tego wydania. Podzielę się moimi odkryciami tutaj, ale nie uważam ich za prawdziwą odpowiedź na problem, ale raczej za obejście tego problemu. Mam jednak nadzieję, że to pomoże komuś.

Najpierw chcę potwierdzić OutOfMemoryException dzieje się w pewnych okolicznościach. Ale, o dziwo, zależy to od układu strony, którego używasz. W rzeczywistości, jeśli Twój układ obejmuje StackPanel, będziesz mieć wyjątek. Chyba sprowadza się to do tego, w jaki sposób metody są implementowane w StackPanel (chociaż mogę być tu całkowicie błędny). Wygląda na to, że gdy ListBox jest dzieckiem do StackPanel, próbuje załadować wszystkie obrazy przed wyświetleniem. To oczywiście powoduje wyciek pamięci.

Z drugiej strony, jeśli jako rodzica jest używana coś w rodzaju Grid jako lista nadrzędna, nie ma takich wyjątków, a obciążenie pamięci jest uzasadnione.

Oto układ strony, który pracował dla mnie:

<Grid> 
    <ListBox ItemsSource="{Binding IsoStorePics}"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <Image local:IsoStoreImageSource.IsoStoreFileName="{Binding Path}" Margin="5"/> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
</Grid> 

To najlepsza odpowiedź Mam dla ciebie. Daj mi znać, jeśli to pomogło.

+0

Myślę, że to nie problem. Próbowałem też coś takiego,

+0

Próbowałem również powyższej metody, o której wspomniałem, ale wynik jest taki sam .. :( –

0

Możesz spróbować w ten sposób, obiekt Stream zostanie automatycznie usunięty.

using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication()) 
{        
    if (iso.FileExists(imagePath)) 
    { 
     using (Stream imagestream = new IsolatedStorageFileStream(imagePath, FileMode.Open, FileAccess.Read, FileShare.Read, iso)) 
     { 
       BitmapImage bmp = new BitmapImage(); 
       bmp.SetSource(imagestream); 
       imgControl.Source = bmp; 
     } 
    } 
} 
Powiązane problemy