我正在使用.net 2.0,我创建了一个表单(System.Windows.Forms.Form),用于在长时间运行的任务中显示信息。
当我开始一个长时间运行的任务时,我创建了这个表单的新实例,调用.Show()并启动BackgroundWorker。但即使我使用BackgroundWorker来完成工作,表单确实显示出来,但是直接阻止并且直到后台工作者完成后才会响应,i.d。表单出现但内容(gif和文本框)未显示?
奇怪的是,当BackgroundWorker的工作密集时,这不会发生!?!怎么会?
示例:
private void UpdateReportingTab()
{
//p is an instance variable; Progressbar is just a simple form control
//showing the passed message
p = new Progressbar("Loading Data...");
p.Show();
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerSupportsCancellation = true;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync();
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
p.BeginInvoke(new MethodInvoker(p.Close));
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new MethodInvoker(delegate()
{
//long running database queries, whose results update text fields
//while text fields are filled p show "no response"
TextEditItems.Text = Convert.ToString(itemsDao.getItemCount());
....
}
}
}
谢谢!
岸堤
答案 0 :(得分:3)
因为你没有有效地运行后台工作人员,所以;)
后台工作人员进入主线程 - 将工作重新放入主UI线程中。
你不应该回想起你需要的东西。
特别地:
你回调的那一刻你回到了UI THREAD上 - 在你的情况下,后台工作者therad只会调用它...这会让后台工作者变得毫无意义。
答案 1 :(得分:2)
通过使用BeginInvoke
,您实际上是在UI线程上执行代码。您的BackgroundWorker
在这里没用,bw_DoWork
将立即返回,用户界面将被冻结。
如果您需要控件中的某些数据,请在之前检索,然后启动BackgroundWorker
,并在BGW线程上执行工作,而不是调用Invoke
或{{ 1}}