OutOfMemory在GDI +中递归绘制矩形时的异常

时间:2014-06-04 16:06:06

标签: c# .net out-of-memory gdi+

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

该代码适用于较小的树,但对于具有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));
            }
        }
    }

}

对代码有什么问题有什么想法吗?或者它可能是GDI +的问题?

1 个答案:

答案 0 :(得分:2)

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