问题
I'm having a memory leak whenever I create any instance of a WriteableBitmap. I've tried multiple suggestions on stackoverflow and other forums, but nothing is working. The basic flow of my test app is this:
- Select an image with the
PhotoChooserTask - Use the
Streamfrom thePhotoResultobject to create aWriteableBitmap.
That's it. Nulling the variables and calling GC.Collect() only solves part of the problem. It keeps the app from allocating memory until the app crashes, but even though the objects have gone out of scope, there is always memory allocated for them until I select a new image. I can reproduce it with the default Windows Phone Direct3D with XAML App. The only modifications to the default project are the following:
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>
回答1:
For this you have to store this file stream inside the IsolatedStorege. So create a filestream using IsolatedStorageFileStream and then save it, like this...
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");
}
}
And for reading you can get that file from 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;
}
This will solved your memory leak problem, try this...
来源:https://stackoverflow.com/questions/18348023/writeablebitmap-memory-leak-in-windows-phone-8