【问题标题】:WriteableBitmap memory leak in Windows Phone 8Windows Phone 8 中的 WriteableBitmap 内存泄漏
【发布时间】:2013-08-23 06:28:45
【问题描述】:

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

  1. 选择带有PhotoChooserTask 的图像
  2. 使用来自PhotoResult 对象的Stream 创建WriteableBitmap

就是这样。清空变量并调用GC.Collect() 只能解决部分问题。它会阻止应用程序分配内存,直到应用程序崩溃,但即使对象超出范围,在我选择新图像之前,总会为它们分配内存。我可以使用带有 XAML 应用程序的默认 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>

【问题讨论】:

  • 您好,我也遇到了这个问题,请问有解决办法吗?

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


【解决方案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;
    }

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

【讨论】:

  • 以上行不通。我已经按照您的指示实现了它,但是当对象超出范围时,内存永远不会被释放。在我通过选择另一个图像创建新对象之前,永远不会收集从初始 Stream 创建的 WriteableBitmap。从隔离存储读取图像似乎很好,并且遵循预期的垃圾收集行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-20
  • 2014-07-01
  • 2014-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多