Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在GDI+中递归绘制矩形时,OutOfMemory异常;_C#_.net_Out Of Memory_Gdi+ - Fatal编程技术网

C# 在GDI+中递归绘制矩形时,OutOfMemory异常;

C# 在GDI+中递归绘制矩形时,OutOfMemory异常;,c#,.net,out-of-memory,gdi+,C#,.net,Out Of Memory,Gdi+,我在使用GDI+在C#中绘制和填充矩形时遇到问题。我试图渲染一个,因此构建了一个递归算法,它从根到叶遍历树结构,并在任何情况下绘制一个矩形,但如果节点恰好是叶节点,则也会填充该矩形 该代码适用于较小的树,但对于具有42层节点的较大数据集,可复制地崩溃。当尝试渲染第16层以下的节点时,上部的DrawRectangle调用抛出OutOfMemoryException,与32-/64位或调试和发布配置无关 画笔和笔不会更改,因此它们存储在方法外部的数组中。创建或处理对象没有问题 下面是我用来渲染树形图

我在使用GDI+在C#中绘制和填充矩形时遇到问题。我试图渲染一个,因此构建了一个递归算法,它从根到叶遍历树结构,并在任何情况下绘制一个矩形,但如果节点恰好是叶节点,则也会填充该矩形

该代码适用于较小的树,但对于具有42层节点的较大数据集,可复制地崩溃。当尝试渲染第16层以下的节点时,上部的
DrawRectangle
调用抛出
OutOfMemoryException
,与32-/64位或调试和发布配置无关

画笔和笔不会更改,因此它们存储在方法外部的数组中。创建或处理对象没有问题

下面是我用来渲染树形图的递归方法:

/// <summary>
/// Renders a certain <see cref="Tree"/> onto the canvas.
/// </summary>
/// <param name="tree">The tree node to be rendered.</param>
/// <param name="g">The <see cref="Graphics"/> canvas to render the tree to.</param>
/// <param name="bounds">The rectangle available for the specified <paramref name="tree"/>.</param>
protected void RenderTree(Tree tree, Graphics g, RectangleF bounds)
{
    if (tree.IsLeaf)
    {
        g.FillRectangle(brushes[tree.Depth], bounds);
        g.DrawRectangle(pens[tree.Depth], bounds);
    }
    else
    {
        g.DrawRectangle(pens[tree.Depth], bounds);

        if (bounds.Width >= bounds.Height)
        {
            float widthPerChild = bounds.Width / (float)tree.Children.Count;
            for (int i = 0; i < tree.Children.Count; ++i)
            {
                RenderTree(tree.Children[i], g, new RectangleF(bounds.X + i * widthPerChild, bounds.Y, widthPerChild, bounds.Height));
            }
        }
        else
        {
            float heightPerChild = bounds.Height / (float)tree.Children.Count;
            for (int i = 0; i < tree.Children.Count; ++i)
            {
                RenderTree(tree.Children[i], g, new RectangleF(bounds.X, bounds.Y + i * heightPerChild, bounds.Width, heightPerChild));
            }
        }
    }

}
//
///在画布上渲染特定的对象。
/// 
///要渲染的树节点。
///要渲染树的画布。
///可用于指定对象的矩形。
受保护的void RenderTree(树、图形g、矩形边界)
{
if(tree.IsLeaf)
{
g、 FillRectangle(画笔[tree.Depth],边界);
g、 DrawRectangle(画笔[tree.Depth],边框);
}
其他的
{
g、 DrawRectangle(画笔[tree.Depth],边框);
如果(bounds.Width>=bounds.Height)
{
float widthPerChild=bounds.Width/(float)tree.Children.Count;
for(int i=0;i

对代码的错误有什么看法吗?还是GDI+有问题?

谢谢您的评论;我可以解决这个问题。我还测试了绘图过程的迭代版本,它没有改变任何东西,但给了我更好的调试选项问题似乎是我试图绘制的矩形太小了(宽度和高度>0,但大约为10^(-5)):在绘制矩形之前,如果矩形的宽度或高度小于1/1000,我添加了一个阈值。当然,这使得
OutOfMemoryException
没有太大帮助,因为您提到的内存问题没有任何可疑行为。

听起来您的递归导致了OOME。您可能想考虑删除递归。只是一个想法,但是也许尝试在每次通过时刷新图形对象。首先检查内存使用和GDI句柄,在这个代码中看不到信号。OOM也可能是由于GDI+错误而产生的,而不仅仅是GC内存不足。使用任务管理器的“流程”选项卡仔细检查您的假设。添加“GDI对象”列,并仔细检查该列是否在1000以下。是否可以尝试注释掉实际图形,或者删除图形参数;这应该有助于澄清它是否确实是GDI+问题。。我试图复制这个,但不知道这棵树,这是不现实的。我想测试从递归中删除图形是否会产生影响,但事实并非如此。当在10000个深度中添加10000个孩子时,我得到OOM,但由于我的树是空的,这可能意味着什么都没有。GDI+因使用OutOfMemoryException报告与内存无关的错误而臭名昭著。