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

本文关键字:创建 情况下 控件 线程 | 更新日期: 2023-09-27 18:15:32

嗨,伙计们,我不明白如何处理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());
                }));
            }
        });
    }

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

你需要给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个子组件。但是,我没有看到任何相关的用例。

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

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