Windows Phone 8中的WriteableBitmap内存泄漏

时间:2013-08-21 02:42:37

标签: c# silverlight xaml mobile windows-phone-8

每当我创建WriteableBitmap的任何实例时,我都会发生内存泄漏。我在stackoverflow和其他论坛上尝试了多个建议,但没有任何工作。我的测试应用程序的基本流程如下:

  1. 使用PhotoChooserTask
  2. 选择图像
  3. 使用Stream对象中的PhotoResult创建WriteableBitmap
  4. 就是这样。取消变量并调用GC.Collect()只能解决部分问题。它使应用程序不会分配内存,直到应用程序崩溃,但即使对象超出范围,在我选择新图像之前总是会为它们分配内存。我可以使用默认的Windows Phone Direct3D和XAML App重现它。对默认项目的唯一修改如下:

    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 个答案:

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

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