c#线程仍然使UI无响应

本文关键字:UI 响应 线程 | 更新日期: 2023-09-27 18:14:50

嗯,我有一个有按钮的form1,如果你点击其中一个按钮它会将UserControl加载到form1

的面板中

usercontrol1包含了很多数据,比如数据库、图表和图片框。所以它肯定会使用户界面在加载时无响应。

所以我读了一些文章,我发现我需要通过另一个线程运行它,所以我试了一下,它只是提高了一点性能。

usercontrol1仍然使GUI无响应大约3-5秒,如果我的数据变大了怎么办?

我想让它具有响应性并通过运行动画picturebox向用户显示仍在加载如果加载完成则停止

下面是我的代码:
private void click_dashb_Click(object sender, EventArgs e)
    {
        ParameterizedThreadStart pts = new ParameterizedThreadStart(load_UserControl);
        Thread t = new Thread(pts);
        t.Start();
        //Animated Picturebox to show user that UI is loading
        pictureBox1.Enabled = true;

        hover.Location = new Point(42, 130);
    }

    private void load_UserControl(object state)
    {
        Invoke(new Action(() =>
        {
            //load user control through another thread
            while (panel1.Controls.Count > 0)
                panel1.Controls[0].Dispose();

            Home frm = new Home();

            frm.AutoScroll = true;
            panel1.Controls.Add(frm);
            frm.Show();
        }));
        //Stop the animated GIF means the load is finish!
        pictureBox1.Enabled = false;
    }

如果你帮我解决这个问题。我可能会把它应用到我所有的作品中。因为其中大部分包含大数据。

感谢stackoverflow社区:)

编辑:

在阅读了建议使用后台工作器的评论后。我试着用它。但还是有一点反应迟钝下面是新代码:

 private void click_dashb_Click(object sender, EventArgs e)
    {
        bgw.RunWorkerAsync();
    }
 private void bgw_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {

            BeginInvoke((MethodInvoker)delegate
            {
                while (panel1.Controls.Count > 0)
                    panel1.Controls[0].Dispose();

                Home frm = new Home();

                frm.AutoScroll = true;
                panel1.Controls.Add(frm);
                frm.Show();
            });

        }
        catch (Exception x)
        {
            MessageBox.Show("An error occured while performing operation" + x);
        }
    }
    private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
    }
    private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Cancelled)
        {
            MessageBox.Show("Operation Cancelled");
        }
        else
        {
            MessageBox.Show("Operation Completed");

        }
    }

好一点了,但还是有点反应迟钝。你能检查一下我的代码,这有什么问题吗?

再次感谢

c#线程仍然使UI无响应

你的代码的问题是,虽然你运行load_UserControl代码在一个新的线程,代码调用调用有效地使所有的代码运行在UI线程再次。我可以想象你这样做,因为访问表单和图片框需要在UI线程上运行。

解决方案(通常)是在一个单独的线程上完成非UI工作,然后切换回UI线程来更新视觉控件。

要做到这一点,你可以方便地使用BackgroundWorker类。在DoWork事件处理程序中,您执行繁重的计算,在RunWorkerCompleted事件处理程序中,您更新控件。如果您愿意,您甚至可以在工作期间通过ProgressChanged事件处理程序更新一些控件(如进度条)。

好吧,仅仅启动一个新线程并不能使UI响应定义。你需要创建一个线程,这样它才能真正并行地做事情。

你的线程没有,因为它基本上执行this.Invoke中的所有代码。

也就是说:你的代码需要this.Invoke中执行,因为几乎所有你做的事情都需要在UI线程上完成。

所以在你的情况下,并行化东西真的没有意义,因为没有办法在不阻塞UI线程的情况下做你想做的事情,而且我知道没有任何技术(线程,任务,BackgroundWorker等)可以解决这个问题。