我想编写一个例程,以从服务器(远程桌面-类似)接收一些jpeg帧,将其转换为位图图像,然后在Windows窗体上显示它们。 我试图使例程尽可能的轻巧,但是也许由于我总是收到System.OutOfMemoryException而做错了。 我的代码如下:

编辑:添加了与此异常相关的部分

private void WatcherRoutine()
    {
        Boolean lLoopEnd = false;
        Bitmap lCurrent = null;
        //Graphics lGraphics = null;
        Image lImg = null;
        BinaryReader lBRVideo = new BinaryReader(this._state.Video.GetStream());

        while (lLoopEnd == false)
        {
            try
            {
                // Reads frame type
                switch (lBRVideo.ReadByte())
                {
                    // Frame received is a big frame (ie a desktop screenshot)
                    case Constants.BIGFRAME:
                        {
                            // Reads frame size in bytes
                            Int32 lVideoLength = lBRVideo.ReadInt32();
                            if (lVideoLength > 0)
                            {
                                // Stores frame in a stream
                                MemoryStream ms = new MemoryStream(lBRVideo.ReadBytes(lVideoLength));
                                // Creates image from stream
                                lImg = Image.FromStream(ms);
                                ms.Dispose();
                                // Creates bitmap from image
                                lCurrent = new Bitmap(lImg);
                                lImg.Dispose();
                                // Passes image to windows form to display it
                                this.Invoke(this._state.dUpdateVideo, lCurrent);
                                    ////lGraphics = Graphics.FromImage(lImg);
                                    //lGraphics.Dispose();
                            }
                        }
                        break;
                    // Diff frame (ie a small part of desktop that has changed)
                    // Commenting this part makes the exception disappear :|
                    case Constants.DIFFFRAME:
                        {
                            Int16 lX = lBRVideo.ReadInt16(),
                                lY = lBRVideo.ReadInt16();
                            Int32 lVideoLength = lBRVideo.ReadInt32();
                            if (lVideoLength > 0)
                            {
                                //Byte[] lVideoImg = lBRVideo.ReadBytes(lVideoLength);
                                //Image lImgDiff = Image.FromStream(new MemoryStream(lVideoImg));
                                ////if(lGraphics != null)
                                //{
                                //    lGraphics.DrawImage(lImgDiff, lX, lY);
                                //    this.Invoke(this._state.dUpdateVideo, new Bitmap(lImg));
                                //}
                            }
                        }
                        break;
                    case Constants.CURSOR:
                        {
                            Int16 lX = lBRVideo.ReadInt16(),
                                lY = lBRVideo.ReadInt16();
                            // TODO
                        }
                        break;
                    default:
                        break;
                }
            }
            catch (Exception e)
            {
                if (this._state.WorkEnd == false)
                {
                    this._state.WorkEnd = true;
                    this.BeginInvoke(this._state.dDisconnect);
                }
                lLoopEnd = true;
                SmartDebug.DWL(e.Message);
            }
        }
    }

dUpdateVideo是一个包含此小例程的委托。.也许我可以释放pBmp了?

private void UpdateVideo(Bitmap pBmp)
    {
        this.VideoPictureBox.Image = pBmp;
    }

===============>>#1 票数:2 已采纳

当您使用基于GDI +的API(System.Drawing)时, OutOfMemory异常并不一定意味着您内存不足。 这也可能意味着传递给GDI +的参数无效或其他原因。 GDI +非常高兴OutOfMemory


如果可能,还应该重用您的内存流。 降低GC的压力很大 您正在分配许多大对象,在这种情况下,GC非常糟糕。


我也认为您永远不会处置lCurrent


然后,您违反了Image.FromStream的约定:

您必须在图像的生命周期内保持流打开:

lImg = Image.FromStream(ms);
ms.Dispose();
lCurrent = new Bitmap(lImg);// `lImage` is used here, but `ms` is already disposed
lImg.Dispose();

Image.FromStream的文档指出:

您必须在图像的生命周期内保持流打开。

ms.Dispose() lImg.Dispose()

===============>>#2 票数:1

一旦我编写了一个程序,该程序处理了从文件加载的大量图像。 我会尽快Dispose所有事情,然后将其余的交给GC。 这还不够,内存使用情况分析清楚地表明,相对于我程序的图像加载速度,GC太慢。 解决的办法是,每当我处理完给定数量的图像时,便手动调用GC.Collect() 请注意, 这不是一个好习惯 ,但有时会有所帮助。 至少值得尝试。

===============>>#3 票数:1

该问题可能与二进制协议错误有关(视频长度以某种方式弄乱了,请参阅lBRVideo.ReadInt16和ReadInt32调用您将其注释掉)

  ask by gc5 translate from so

未解决问题?本站智能推荐:

1回复

未处理OutOfMemoryException

我更改了使用Accord.NET应用程序自动缝合图像以缝合多个文件。 我在btnDoItAll代码上放置了一个for loop ,该循环将取决于要缝合的图像数量。 我在循环末尾加入了裁剪代码。 你可以在这里看到。 出现一个错误,指出OutOfMemoryException was
2回复

大的,每像素1位的位图导致OutOfMemoryException

我想做的是从磁盘加载图像并从中创建一个BitmapSource 。 图像为14043px x 9933px,为b / w(1bpp)。 但我遇到OutOfMemoryException因为以下代码消耗大约800 MB RAM。 以下代码在我的特定文件的维度中生成ImageSource
1回复

System.Drawing.Image中的内存不足异常

我需要调整3种不同大小的文件上传图像的大小(每个图像),并将它们的路径保存到数据库中。 我为此写了belove方法。 } 方法调用: 问题是,我第二次在运行时调用此方法, System.Drawing.Image img = System.Drawing.Image.
1回复

自Windows 10 1709更新以来-System.OutOfMemoryException c#.net

我的winforms应用程序一直运行良好,直到最新的Windows 10 1709更新为止,此后更新运行我的应用程序在运行独立的.exe或Visual Studio 2017时不断崩溃。该应用程序在具有最新1709更新的任何计算机上崩溃。 作为测试,我创建了一台Windows 7计算机,并且可
2回复

ImageList / Image OutOfMemoryException

从ImageList获取图像时,我遇到OutOfMemoryException我一直无法找到问题的合适解决方案。 我有一个Custom ListView控件,它附加了一个用于绘制ListViewItems的事件。 然后调用一个静态方法来设计绘制项目。 对于大约300个项目的List
2回复

OutOfMemoryException将许多图像帧添加到图像列表

尝试使用SelectActiveFrame将图像帧添加到图像列表时,出现“内存不足”异常。 如果我处理的页数少于174页,那么所有方法都可以100%工作,但是任何超出此范围的操作都会产生此错误。 用最简单的形式,我的代码是:
3回复

System.Drawing.Image.FromStream()上的Out of Memory异常

我有一个应用程序,它处理和重新调整图像大小和偶尔在长迭代期间我得到OutOfMemoryException。 我将我的图像作为文件流存储在数据库中,在处理过程中我需要将它们保存到临时物理位置。 我的模特: 处理看起来大致如下: 我看过这个类似的帖子,但没有一个答案似乎
3回复

c#使用System.Drawing.Image超出内存异常

我想用2张图片创建一个pdf。 其中一个图像是文本,另一个是在第一个图像之上绘制的水印。 好吧,当我加载第一个图像时一切正常,但后来我尝试加载水印图像并获得“Out of Memory”异常。 我有记忆(打印内存使用量大约是20MB)并且可以在我的计算机中打开图像(我使用的是我从谷歌那里测
12回复

什么是一种有效的方法来判断位图是否完全是黑色的?

我想知道是否有一种确保Image对象引用完全黑色图像的超高效方法,因此位图中的每个像素都是ARGB(255,0,0,0)。 你会推荐什么? 这些位图中的大多数将是1024 x 6000像素(尽管假设它们总是那么大,这是不安全的)。 我需要这个,因为我们遇到了PrintWindow
1回复

为什么我得到System.OutOfMemoryException

我正在使用Linq到Sql。 这是代码: 它在64位计算机上运行,​​编译为AnyCPU。 它引发System.OutOfMemoryException。 这将访问SQL Server数据库。 Id字段映射到SQL Server int字段,而Text字段映射到Text(nv