如何在不阻塞主线程的情况下创建大量控件?

时间:2016-10-28 09:24:02

标签: c# wpf multithreading

大家好,我不明白如何处理UI线程,所以我尝试在子线程中创建许多UI元素,但是, 如何修改以下代码,以便窗口不会阻止:

    public void CreateCtr(string name)
    {
        Button btn = new Button();
        btn.Content = name;
        btn.Width = 10;
        btn.Height = 10;
        content.Children.Add(btn);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        int count = 100000;
        Task.Factory.StartNew(()=> {
            for (int i = 0; i < count; i++)
            {
                this.Dispatcher.BeginInvoke(new Action(()=> {
                    CreateCtr(i.ToString());
                }));
            }
        });
    }

2 个答案:

答案 0 :(得分:0)

您需要为UI线程提供一些空间来呼吸。使用当前代码,UI线程正忙于处理所有创建按钮任务,并且无法处理用户输入。在创建每个按钮之间设置最小的暂停。几毫秒就足够了:

private void Button_Click(object sender, RoutedEventArgs e)
{
    int count = 100000;
    Task.Factory.StartNew(() => {
        for (int i = 0; i < count; i++)
        {
            this.Dispatcher.BeginInvoke(new Action(() => {
                CreateCtr(i.ToString());
            }));
            Thread.Sleep(5);
        }
    });
}

暂停时间越长,表单响应越快。

您会注意到表单在一段时间后再次响应性降低,因为在表单上的一定数量的组件之后,添加另一个组件需要很长时间。这是我原来的评论变得相关的地方:在表单上有很多组件是没有用的,所以框架不能很好地处理它。

可能有效的不是将所有按钮放在同一个父容器上,而是创建一个组件树,其中每个组件只有100个子组件。但同样:我没有看到任何相关的用例。

答案 1 :(得分:0)

添加控件时可能会禁用调度程序。

int count = 100000;
Task.Factory.StartNew(() => {
    using (var d = Dispatcher.DisableProcessing())
    {
        for (int i = 0; i < count; i++)
        {
            this.Dispatcher.BeginInvoke(new Action(()=> {
                CreateCtr(i.ToString());
            }));
        }
    }
});