OutOfMemory Exception when recursively drawing rectangles in GDI+

强颜欢笑 提交于 2019-12-12 15:47:01

问题


I have a problem drawing and filling rectangles in C# using GDI+. I'm trying to render a treemap and have therefore constructed a recursive algorithm which traverses the tree structure from root to leaf levels and draws a rectangle in any case, but also fills the rectangle if the node happens to be a leaf node.

The code works fine for smaller trees, but reproducably crashes for a larger data set which has 42 layers of nodes. The upper DrawRectangle call throws an OutOfMemoryException when trying to render a node below the 16th layer, independent of 32-/64-bit or debug and release configurations.

Brushes and Pens are not subject to change, so they are stored in an array outside the method. There is no problem with creating or disposing objects.

Here is the recursive method I use to render the treemap:

/// <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));
            }
        }
    }

}

Are there any ideas on what is wrong with the code? Or could it be a problem with GDI+?


回答1:


Thank you for all the comments; I could solve the problem. I also tested an iterative version of the drawing process and it did not change anything but gave me better debugging options. The problem seems to have been that the rectangles I tried to draw were too small (width and height > 0, but around 10^(-5)): Before drawing the rectangles, I added a threshold if the width or height of the rectangle is less than 1/1000. Of course, this makes an OutOfMemoryException not very helpful as none of the memory issues you remarked showed any suspicious behavior.



来源:https://stackoverflow.com/questions/24042367/outofmemory-exception-when-recursively-drawing-rectangles-in-gdi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!