StackOverFlowException - 但显然不是递归/无限循环

时间:2011-01-08 03:00:28

标签: c# .net image memorystream stack-overflow

我现在被这个问题阻挡了一整天,阅读了数以千计的谷歌搜索结果,但似乎没有什么能反映我的问题甚至接近它...我希望你们中的任何一个人都朝着正确的方向前进我

我写了一个客户端 - 服务器 - 应用程序(更像是2个应用程序) - 客户端收集有关他的系统的数据,以及截图,将所有这些序列化为XML流(图片为byte [] - 数组])并定期将其发送到服务器。 服务器接收流(通过tcp),将xml反序列化为信息对象,并在Windows窗体上显示信息。 该过程以3秒的提交间隔稳定运行约20-25分钟。在观察内存使用时,没有什么重要的东西可以看,也有点稳定。但是在这20-25分钟之后,服务器会在它反序列化tcp-stream时抛出一个StackOverflowException,尤其是在从byte [] - array设置Image属性时。

我彻底搜索了递归或无限循环,并且考虑到它发生在数千个成功的间隔之后,我几乎无法想象。

    public byte[] ImageBase
    {
        get
        {
            MemoryStream ms = new MemoryStream();
            _screen.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            return ms.GetBuffer();
        }
        set
        {
            if (_screen != null) _screen.Dispose(); //preventing well-known image memory leak
            MemoryStream ms = new MemoryStream(value);
            try
            {
                _screen = Image.FromStream(ms); //<< EXCEPTION THROWING HERE
            }
            catch (StackOverflowException ex) //thx to new CLR management this wont work anymore -.-
            {
                Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
            }
            ms.Dispose();
            ms = null;
        }
    }

我希望不需要更多的代码,否则它会变得非常复杂......

请帮助,我完全不知道了

THX 克里斯

3 个答案:

答案 0 :(得分:3)

您可能想要阅读此内容。 Loading an image from a stream without keeping the stream open

似乎有可能在堆栈或其他最终吹掉堆栈的对象上维护流。

我的建议是,然后抓住byte[]并等到最后一刻解码并绘制它。然后立即处理图像。您的get / set将设置/获取byte[]。然后,您将实现一个自定义绘图例程,该例程将对当前byte[]进行解码并绘制它,确保不会占用任何超出必要的资源。

<强>更新

如果有办法可以让我们获得完整的堆栈跟踪,我们可以进一步提供帮助。我开始认为这不是我描述的问题。我创建了一个示例程序,创建了10,000个图像,就像在setter中一样,没有问题。如果您每隔3秒发送一次图像,那么30张图像每分钟20分钟,这只有600张图像。

我对此解决方案非常感兴趣。我稍后再回来。

然而,有一些可能性是遥远的。

  • Image.FromStream正在尝试处理无效/损坏的byte [],并且该方法以某种方式使用递归来解码位图。非常不可能。
  • 在您认为的情况下,不会抛出异常。如果可能的话,完整的堆栈跟踪将非常有用。正如您所说,您无法捕获StackOverflowException。如果您通过调试器运行它,我相信有这样的规定。

答案 1 :(得分:3)

我怀疑这不是您发布的代码,而是从TCP流中读取的代码正在增加堆栈。秸秆打破驼背的事实发生在Image.FromStream期间可能无关紧要。我经常看到人们编写包含自我调用代码的套接字处理代码(有时间接地,如A - > B - > A - > B)。您应该检查该代码并将其发布在此处供我们查看。

答案 2 :(得分:1)

我不确定它是否相关,但Image.FromStream的MSDN文档说明了这一点 您必须在图片的生命周期内保持流打开。

相关问题