2013-08-21 73 views
6

每次创建WriteableBitmap的任何实例时,都会发生内存泄漏。我已经尝试了多个stackoverflow和其他论坛上的建议,但没有任何工作。我的测试应用程序的基本流程是这样的:Windows Phone 8中的WriteableBitmap内存泄漏

  1. PhotoChooserTask
  2. 使用StreamPhotoResult对象选择图像创建WriteableBitmap

就是这样。忽略变量并调用GC.Collect()只能解决部分问题。它使应用程序不会分配内存,直到应用程序崩溃,但即使对象已超出范围,在我选择新图像之前总会分配内存。我可以使用带有XAML App的默认Windows Phone Direct3D重现它。唯一的修改默认的项目如下:

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

嗨,我也遇到过这个问题,任何解决方案呢? –

回答

-1

对于这一点,你必须存储IsolatedStorege这里面的文件流。因此,使用IsolatedStorageFileStream创建一个文件流,然后将其保存,像这样...

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

    } 

以及用于读取你可以从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; 
    } 

这将解决你的内存泄漏问题,试试这个...

+1

以上不起作用。我已经按照你的指示实现了它,但是当对象超出范围时内存不会被释放。直到我通过选择另一个图像创建一个新对象时,从初始Stream创建的WriteableBitmap才会被收集。从孤立的存储中读取图像似乎很好,并遵循预期的垃圾收集行为。 – Wagan8r