C#:尽管BackgroundWorker

C#:尽管BackgroundWorker,c#,.net,winforms,user-interface,backgroundworker,C#,.net,Winforms,User Interface,Backgroundworker,我使用的是.NET2.0,我创建了一个表单(System.Windows.Forms.form),用于在长时间运行的任务中显示信息 当我启动一个长时间运行的任务时,我会创建这个表单的一个新实例call.Show()并启动BackgroundWorker。但是,即使我使用BackgroundWorker来做这项工作,表单确实会显示出来,但在后台工作人员完成之前,表单会立即阻塞并且不会响应,即表单会出现,但内容(gif和文本框)不会显示 奇怪的是,当后台工作人员的工作如此密集时,这种情况就不会发生!

我使用的是.NET2.0,我创建了一个表单(System.Windows.Forms.form),用于在长时间运行的任务中显示信息

当我启动一个长时间运行的任务时,我会创建这个表单的一个新实例call.Show()并启动BackgroundWorker。但是,即使我使用BackgroundWorker来做这项工作,表单确实会显示出来,但在后台工作人员完成之前,表单会立即阻塞并且不会响应,即表单会出现,但内容(gif和文本框)不会显示

奇怪的是,当后台工作人员的工作如此密集时,这种情况就不会发生!?!为什么

例如:

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


安迪

因为你没有有效地管理后台工作人员,伙计;)

后台工作线程调用主线程-这将工作放回到主UI线程中

除非需要,否则不应调用BACK

特别是:

  • 进行长时间运行的数据库查询,检索结果
  • 然后调用回UI线程以更新TextEditItems

当你回调用时,你就回到了UI线程上——在你的例子中,后台工作线程therad只回调用。。。这使得后台工作人员毫无意义。

因为你没有有效地运行后台工作人员,伙计;)

后台工作线程调用主线程-这将工作放回到主UI线程中

除非需要,否则不应调用BACK

特别是:

  • 进行长时间运行的数据库查询,检索结果
  • 然后调用回UI线程以更新TextEditItems

当你回调用时,你就回到了UI线程上——在你的例子中,后台工作线程therad只回调用。。。这使得后台工作程序毫无意义。

通过使用
BeginInvoke
,您实际上是在UI线程上执行代码。您的
BackgroundWorker
在这里没有用处,
bw\u-dowwork
将立即返回,UI将被冻结


如果您需要从控件中获取一些数据,请在启动
BackgroundWorker
之前检索这些数据,并在BGW线程上执行这些工作,而不是使用
BeginInvoke
调用
BeginInvoke
,实际上是在UI线程上执行代码。您的
BackgroundWorker
在这里没有用处,
bw\u-dowwork
将立即返回,UI将被冻结

如果需要控件中的一些数据,请在启动
BackgroundWorker
之前检索这些数据,并在BGW线程上执行这些工作,而不是调用
Invoke
BeginInvoke