好吧,我有一个带有按钮的form1,如果你单击其中一个按钮 它会将UserControl加载到form1
中的面板中usercontrol1也包含很多数据,如数据库,图表和图片框。因此,加载时肯定会使用户界面无响应。
所以我读了一些文章,我发现我需要通过另一个线程运行它,所以我尝试了它,它只是稍微提高了性能。
usercontrol1仍然会使GUI无响应约3-5秒,如果我的数据变大了怎么办。
我想让它响应并向用户显示仍然通过运行动画图片框加载并停止,如果它完成加载
这是我的代码:
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");
}
}
它好一点但我仍然有点反应迟钝。你能看看我的代码以及它的错误吗?
再次感谢
答案 0 :(得分:0)
您的代码的问题在于,虽然您在新线程中运行load_UserControl代码,但该代码调用Invoke,这有效地使代码再次在UI线程上运行。我可以想象你这样做,因为访问Forms和PictureBoxes需要在UI线程上运行。
解决方案(通常)是在单独的线程上进行非UI工作,然后切换回UI线程以更新可视控件。
为此,您可以方便地使用BackgroundWorker类。在DoWork事件处理程序中,您执行繁重的计算,在RunWorkerCompleted事件处理程序中更新控件。如果需要,您甚至可以通过ProgressChanged事件处理程序在工作期间更新某些控件(如进度条)。
答案 1 :(得分:0)
好吧,刚开始一个新线程并没有按照定义使UI响应。你需要创建线程,以便它实际上并行执行。
你的线程没有,因为它基本上执行this.Invoke
中的所有代码。
话虽如此:您的代码需要在this.Invoke
中执行,因为几乎所有操作都需要在UI线程上完成。
所以在你的情况下,并行化东西真的没有意义,因为在没有阻止UI线程的情况下没有办法做你想做的事情而且没有我知道的技术(线程,任务) ,BackgroundWorker等)将解决这个问题。