内存流对内存/内存c#wpf有多大影响?

时间:2018-03-20 16:13:09

标签: c# wpf memorystream

我目前对我的应用程序非常困惑:(。我的应用程序占用了太多内存..

基本上我的应用程序是一个WPF应用程序,它有3-4个窗口和几个页面,每个窗口/根据需要打开/显示。每个窗口/页面有几个Image控件来显示图像。要检索图像(来自资源),我使用以下功能:

public BitmapImage LoadImage(Uri uri, bool LoadOnMemory, int Pixel)
{
if (LoadOnMemory == true)
{
    System.Windows.Resources.StreamResourceInfo sri = Application.GetResourceStream(uri);
    System.IO.BinaryReader binReader = new System.IO.BinaryReader(sri.Stream);
    byte[] buffer = binReader.ReadBytes(sri.Stream.Length);
    using (MemoryStream memoryStream = new MemoryStream(buffer))
    {
        BitmapImage bi = new BitmapImage();
        bi.BeginInit();
        bi.CacheOption = BitmapCacheOption.Default;
        bi.CreateOptions = BitmapCreateOptions.None;
        bi.StreamSource = memoryStream;
        bi.DecodePixelWidth = Pixel;
        bi.EndInit();
        bi.Freeze();
        return bi;
    }
}
else
{
    BitmapImage bi = new BitmapImage();
    bi.BeginInit();
    bi.CacheOption = BitmapCacheOption.Default;
    bi.CreateOptions = BitmapCreateOptions.None;
    bi.UriSource = uri;
    bi.DecodePixelWidth = Pixel;
    bi.EndInit();
    bi.Freeze();
    return bi;
}
}

我有,可能总共20张图片并加载每张图片,该功能称为设置Pixel到30(或有时40)和LoadOnMemoryTrue。我的启动窗口有2个图像和一个TextBlock,调用相同的函数来加载两个图像。

只要我的应用启动,在任务管理器中,我就会看到即使只有2-3行代码加载MainWindow的启动画面也会耗尽105+当我的MainWindow加载时,RAM /内存的消耗达到200+ mb。主窗口调用函数couple o'因为MainWindow中有近10张图片。从那时起,无论有多少PageWindow s我打开任何数量的图像,RAM的消耗都保持不变同样的。由于某种原因,它不会超过220+ mb。

我怀疑由于我的函数使用MemoryStream,这可能是导致如此大量内存消耗的原因。

但后来我创建了一个没有代码隐藏的虚拟窗口,只是一个空白窗口并启动了我的应用程序......即使是空白窗口也会消耗100多亿内存!!

但虚拟窗口不是我的关注,我的问题是,如果例如,我的应用程序有20个图像,每个图像使用该功能加载(或者我应该说是内存流),它对ram有多大影响? (虽然我可以看到它使用了近200 mb)。我的功能在应用程序中不会导致任何延迟/性能问题,但我只需要知道该函数是否对这么大的内存消耗负责?

更新:很抱歉提供有关空白窗口的误导性信息

直到现在我在VS内运行应用程序,因此内存的总消耗实际上是 Intellitrace(吃掉超过30mb)空白窗口(15)的总和-20 mb max ....

最后一个qs,因为我也更新了代码,哪个更好?关于应用程序性能和内存消耗的代码的第二部分(不使用memorystream)或第一部分(使用memoryStream)?

1 个答案:

答案 0 :(得分:3)

当您可以直接从StreamResourceInfo的Stream加载BitmapImage时,您当然不需要中间MemoryStream:

private ImageSource LoadImage(Uri resourceUri, int pixelWidth)
{
    var resource = Application.GetResourceStream(resourceUri);
    var bitmap = new BitmapImage();

    using (var stream = resource.Stream)
    {
        bitmap.BeginInit();
        bitmap.CacheOption = BitmapCacheOption.OnLoad;
        bitmap.StreamSource = stream;
        bitmap.DecodePixelWidth = pixelWidth;
        bitmap.EndInit();
        bitmap.Freeze();
    }

    return bitmap;
}

但是,您根本不需要使用Stream,这显然更简单:

private ImageSource LoadImage(Uri resourceUri, int pixelWidth)
{
    var bitmap = new BitmapImage();
    bitmap.BeginInit();
    bitmap.CacheOption = BitmapCacheOption.OnLoad;
    bitmap.UriSource = resourceUri;
    bitmap.DecodePixelWidth = pixelWidth;
    bitmap.EndInit();
    bitmap.Freeze();
    return bitmap;
}