2013-04-22 19 views
8

Nella mia applicazione sto utilizzando il metodo di supporto indicato di seguito per collegare l'immagine di archiviazione isolata al controllo Immagine. Ho ottenuto questo metodo di supporto dal link "Binding Image stored in the Isolated Storage to Image Control in Windows Phone"L'app si arresta in modo anomalo durante il tentativo di associare l'immagine di archiviazione isolata

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

}

Sto usando questo all'interno di un controllo ListBox. E se provi con le immagini di libreria predefinite, tutto funzionerà come previsto. Ma se provo con le immagini di grandi dimensioni (scattate tramite la fotocamera del dispositivo) l'app si blocca.

E qui è l'eccezione che cosa sto ottenendo

Un'eccezione di tipo 'System.OutOfMemoryException' avvenuto in System.Windows.ni.dll ma non è stata gestita nel codice utente

dello stack trace

a MS.Internal.FrameworkCallbacks.NotifyManagedDebuggerOnNativeOOM() a MS.Internal.XcpImports.BitmapSource_SetSource (BitmapSource BitmapSource, cValue & Bytestream) a System.Windows.Media.Imaging.BitmapSource.SetSourceInternal (stream flussi ource) a System.Windows.Media.Imaging.BitmapImage.SetSourceInternal (Stream streamSource) a System.Windows.Media.Imaging.BitmapSource.SetSource (Stream streamSource) su MyaPP.Common.IsoStoreImageSource. <> c__DisplayClass4. <> c__DisplayClass6.b__1 (oggetto _)

+0

Quante immagini visualizzate nell'elenco? Quanto sono grandi?Puoi eseguire l'analisi della memoria sulla tua app ('Debug -> Avvia Analisi applicazioni Windows Phone -> Profilazione -> Memoria' in Visual Studio) e pubblicare i risultati? – Haspemulator

+0

Prova a utilizzare LongListSelector come elenco semplice – Mahantesh

+2

@Haspemulator: il problema è menzionato qui "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", Come posso risolvere questo problema con la tua implementazione. –

risposta

0

La memorizzazione nella cache dello ListBox potrebbe occupare la memoria e ciò è particolarmente evidente con immagini più grandi. Non ho familiarità con il metodo di supporto che hai pubblicato ma prova ad aggiungerlo.

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

    //rest of the code ... 
} 
0

OK, ci è voluto del tempo per tornare a questo problema. Condividerò i miei risultati qui, ma non li considero una vera risposta al problema, ma piuttosto una soluzione alternativa. Tuttavia, spero che possa aiutare qualcuno.

Per prima cosa voglio confermare che lo OutOfMemoryException si verifica in determinate circostanze. Ma, sorprendentemente, dipende dal layout della pagina che stai utilizzando. Infatti, se il tuo layout coinvolge StackPanel, avrai un'eccezione. Immagino, si tratta del fatto che i metodi MeasureOverride e ArrangeOverride sono implementati in StackPanel (anche se potrei sbagliarmi completamente qui). Sembra che quando ListBox è figlio a StackPanel, prova a caricare tutte le immagini prima di visualizzarle. Questo, naturalmente, causa la perdita di memoria.

D'altra parte, se si utilizza qualcosa come Grid come genitore per l'elenco di immagini, quindi non ci sono tali eccezioni e il carico di memoria è ragionevole.

Ecco layout di pagina che ha funzionato per me:

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

Questa è la migliore risposta che ho per voi oggi. Per favore fatemi sapere se ha aiutato.

+0

Penso che non sia il problema. Ho provato qualcosa di simile,

+0

E inoltre ho provato il metodo sopra menzionato, ma il risultato è lo stesso .. :( –

0

Si può provare in questo modo, l'oggetto Stream verrà eliminato automaticamente.

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