为什么这种方法工作这么慢?

时间:2012-09-02 09:40:39

标签: c# .net winforms graphics gdi+

我编写了一个Windows Forms C#应用程序,用于绘制像行一样的矢量基元。椭圆等我有一个方法来改变所选图形的边框宽度。这是方法:

   public void SetBorderWidth(int border)
    {
        if (border < 0) 
            return;

        if ((SelectedItem != null) && (SelectedItem.isGroup == false)) 
        {              
            SelectedItem.BorderWidth = border;
        }

        if ((SelectedItem != null) && (SelectedItem.isGroup == true))
        {

            ChangeCascadeBorderWidth(SelectedItem, border);
        }

        foreach (Shape figure in ObjectsDrawn)
        {
            if (figure.Selected)
            {
                ObjectsDrawn[ObjectsDrawn.IndexOf(figure)].BorderWidth = border;
            }

            if (figure.isGroup)
            {
                ChangeCascadeBorderWidth(figure, border);
            }
        }            
    }

谁调用该方法:

    private void ChangeCascadeBorderWidth(Shape group, int width)
    {
        foreach (Shape item in ((Grouping)group).GroupedElements)
        {
            if (item.isGroup == true)
            {
                ChangeCascadeBorderWidth(item, width);
            }
            else
            {
                item.BorderWidth = width;
            }
        }
    }

如果数字是几个数字的组合。但这种做法太慢了。无论我选择了一组还是一组数字,有时我都需要等待10-15秒。用于改变边框宽度。为什么这么慢?

3 个答案:

答案 0 :(得分:0)

我的想法:

一个像素的宽度可以提高性能,因为可以使用基于行的基元渲染边框。

当您使用大于1的宽度时,它必须使用固体填充的基元,这将很慢。

答案 1 :(得分:0)

您的代码正在编辑SelectedItem的边框,任何将Selected属性设置为true的ObjectDrawn,以及绘制属于某个组的所有对象的边框。

您是否也要根据是否选择了组形状来过滤您的组边框图? figure.isGroup && figure.Selected 否则,它似乎会修改所有组的边界,如果有很多组,可能会导致性能问题,无论您选择了什么。

其他绩效改进建议:
你在SetBorderWidth中执行此操作:
    ObjectsDrawn[ObjectsDrawn.IndexOf(figure)].BorderWidth = border; 但是你在ChangeCascadeBorderWidth中这样做:     item.BorderWidth = width; 我建议在SetBorderWidth函数中执行相同的操作,你已经拥有了要修改的对象的实例,IndexOf查找似乎不是必需的。

另外,如果设置BorderWidth属性的成本很高(即使设置为相同的现有值),那么将调用包装到SetBorderWidth,如下所示: if(item.BorderWidth != width) item.BorderWidth = width;可以节省性能。但是,您必须评估比较的成本与设置边框宽度的成本。

答案 2 :(得分:0)

您发布的所有瓶颈似乎都来自于在形状上设置BorderWidth属性。我猜你在重新绘制或更新BorderWidth中的形状布局。如果在容器上设置BorderWidth,会有很多不必要的重绘和布局更改,这在WinForms中很慢(特别是对于布局,如果你的形状继承自Control)。

我可以像其他一些WinForms控件一样建议 BeginUpdate * EndUpdate *机制吗?