【问题标题】:When using System.IO.Stream, how can I avoid OutOfMemoryException?使用 System.IO.Stream 时,如何避免 OutOfMemoryException?
【发布时间】:2017-08-02 07:57:10
【问题描述】:

我正在制作一个扫描组件,但是当我为文档设置高分辨率 (600 dpi) 时,我往往会在 1 或 2 次扫描后得到 System.OutOfMemoryException

我的代码如下

public ScannedImage SaveScannedImage(DataTransferredEventArgs e)
{
    if (e == null) throw new IOException();

    BitmapSource fullResImage;
    using (var fullResImageStream = e.GetNativeImageStream())
    {
        fullResImage = fullResImageStream.ConvertToWpfBitmap(e.ImageInfo.ImageWidth, e.ImageInfo.ImageLength);
    }

    BitmapSource lowResImage;
    using (var lowResImageStream = e.GetNativeImageStream())
    {
        lowResImage = lowResImageStream.ConvertToWpfBitmap(800, 0);
    }

    return new ScannedImage(lowResImage, fullResImage);
}

这通常发生在

using (var lowResImageStream = e.GetNativeImageStream())

我们将不胜感激。

【问题讨论】:

  • 在处理Stream时,在不需要时使用GC.Collect()方法收集非托管资源。
  • 你确定ImageLength 是你想要的,而不是例如ImageHeight? DataTransferredEventArgsConvertToWpfBitmap 等是什么?
  • @ManpritSinghSahota GC.Collect() 应该在它看到它的内存不足时调用,当它仍然内存不足时它会抛出。但确实GC.Collect() 有时会解决问题,即使它不应该
  • 我正在使用 Twain API。 DataTransferredEventArgs 包含来自扫描仪的事件数据,ConvertToWpfBitmap 是内置的 BitmapSource 方法,可将传入的 System.IO.Stream 转换为可显示的 WPF 图像。

标签: c# stream out-of-memory bitmapsource


【解决方案1】:

您看到的可能是大对象堆 (LOH) 碎片造成的。

这很难避免,但您可以显式压缩 LOH。

GCSettings.LargeObjectHeapCompactionMode = 
    GCLargeObjectHeapCompactionMode.CompactOnce;

GC.Collect();

另外,请确保您作为 64 位进程运行。开启“首选 32 位”选项(如果已打开)。

有关更多信息,您可能需要阅读

【讨论】:

  • @AkselVincentBerg 那么,你看过了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-23
  • 1970-01-01
  • 2012-08-12
  • 1970-01-01
  • 1970-01-01
  • 2011-08-14
  • 2021-01-02
相关资源
最近更新 更多