2013-08-21 8 views
6

Sto avendo una perdita di memoria ogni volta che creo una qualsiasi istanza di un WriteableBitmap. Ho provato più suggerimenti su StackOverflow e altri forum, ma non funziona nulla. Il flusso di base del mio test app è questo:WriteableBitmap perdita di memoria in Windows Phone 8

  1. Selezionare un'immagine con il PhotoChooserTask
  2. Utilizzare il Stream dall'oggetto PhotoResult per creare un WriteableBitmap.

Questo è tutto. Nulling le variabili e chiamando GC.Collect() risolve solo parte del problema. Mantiene l'applicazione da allocazione di memoria fino a quando l'applicazione si blocca, ma anche se gli oggetti sono andati fuori del campo di applicazione, c'è sempre memoria allocata per loro fino a quando seleziono una nuova immagine. Posso riprodurlo con Windows Phone Direct3D predefinito con XAML App. Le uniche modifiche al progetto di default sono le seguenti:

MainPage.xaml.cs

public MainPage() { 
    InitializeComponent(); 
    _photoChooserTask = new PhotoChooserTask(); 
    _photoChooserTask.Completed += new EventHandler<PhotoResult>(photoChooserTaskComplete); 
} 

private void ApplicationBarIconButton_Click(object sender, EventArgs e) { 
    _photoChooserTask.Show(); 
} 

private void photoChooserTaskComplete(object sender, PhotoResult e) { 
    if (e.TaskResult == TaskResult.OK) { 
     BitmapImage image = new BitmapImage(); 
     image.SetSource(e.ChosenPhoto); 
     WriteableBitmap wbm = new WriteableBitmap(image); 
     image.UriSource = null; 
     image = null; 
     wbm = null; 
     GC.Collect(); 
    } 
} 

MainPage.xaml

<phone:PhoneApplicationPage.ApplicationBar> 
    <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True" Mode="Default" Opacity="0.5" > 
     <shell:ApplicationBar.Buttons> 
      <shell:ApplicationBarIconButton IconUri="/junkUrl.png" Text="albums" Click="ApplicationBarIconButton_Click" /> 
     </shell:ApplicationBar.Buttons> 
    </shell:ApplicationBar> 
</phone:PhoneApplicationPage.ApplicationBar> 
+0

Ciao, ho verifica questo problema, così, qualsiasi soluzione ancora? –

risposta

-1

Per questo è necessario conservare questo flusso di file all'interno del IsolatedStorege. Quindi creare un FileStream utilizzando IsolatedStorageFileStream e quindi salvarlo, come questo ...

private void photoChooserTaskComplete(object sender, PhotoResult e) { 
if (e.TaskResult == TaskResult.OK) { 
     SaveToIsolatedStorage(e.ChosenPhoto,"Your File Name");   
} 

}

public void SaveToIsolatedStorage(Stream imageStream, string fileName) 
    { 
     try 
     { 
      string imagename = fileName + ".jpg"; 
      using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication()) 
      { 
       if (myIsolatedStorage.FileExists(imagename)) 
       { 
        myIsolatedStorage.DeleteFile(imagename); 
       } 
       IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile(imagename); 
       WriteableBitmap wb = new WriteableBitmap(100, 100); 
       wb.SetSource(imageStream); 
       wb.SaveJpeg(fileStream, 100, 100, 0, 70); 
       fileStream.Close(); 
      } 
     } 

     catch (Exception) 
     { 
      RadMessageBox.Show(String.Empty, MessageBoxButtons.OK, "Error occured while saving Images");        
     } 

    } 

e per la lettura è possibile ottenere tale file dal IsolatedStorage

public WriteableBitmap ReadFromIsolatedStorage(string fileName) 
    { 
     WriteableBitmap bitmap = new WriteableBitmap(100, 100); 
     try 
     { 
      using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication()) 
      { 
       if (myIsolatedStorage.FileExists(fileName)) 
       { 

        using (IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile(fileName, FileMode.Open, FileAccess.Read)) 
        { 
         // Decode the JPEG stream.        
         bitmap = PictureDecoder.DecodeJpeg(fileStream, 100, 100); 
        } 
       } 
      } 
     } 
     catch (Exception) 
     { 
      RadMessageBox.Show(String.Empty, MessageBoxButtons.OK, "Error Occcured while reading image");        
     } 


     return bitmap; 
    } 

Questa volontà risolto il problema di perdita di memoria, provate questo ...

+1

Quanto sopra non funziona. L'ho implementato come da istruzioni, ma la memoria non viene mai rilasciata quando gli oggetti escono dall'ambito. La WriteableBitmap creata dal flusso iniziale non viene mai raccolta finché non creo un nuovo oggetto selezionando un'altra immagine. Leggere l'immagine dallo storage isolato sembra essere soddisfacente e seguire il comportamento previsto della raccolta dei rifiuti. – Wagan8r