当前位置: 动力学知识库 > 问答 > 编程问答 >

.net - C#: Popup form blocking despite BackgroundWorker

问题描述:

I'm using .net 2.0 and I've created a form (System.Windows.Forms.Form) for displaying information during long running tasks.

When I start a long running task, I create a new instance of this form, call .Show() and start the BackgroundWorker. But even though I use a BackgroundWorker for doing the work, the form indeed shows up, but immediatly blocks and doesn't response until the background worker has finished, i.d. the form appears but the content (a gif and a textbox) isn't shown?

The strange thing is, this doesn't happen when the job for the BackgroundWorker is that intensive!?! How come?

Example:

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

....

}

}

}

Thanks!

Andi

网友答案:

Because you do not effectively run a background worker, dude ;)

The background worker INVOKES INTO THE MAIN THREAD - which puts the work back into the main UI thread where.

You should NOT INVOKE BACK UNTL YOU NEED To.

Particularly:

  • Make the long running database query, retrieve the results
  • THEN invoke back into the UI thread to update the TextEditItems

The moment you invoke back you are back on the UI THREAD - in your case the background worker therad does only the invoke back... which makes the background worker senseless.

网友答案:

By using BeginInvoke, you're actually executing the code on the UI thread. Your BackgroundWorker is useless here, the bw_DoWork will return immediately and the UI will be frozen.

If you need some data from the controls, retrieve it before you start the BackgroundWorker, and do the work on the BGW thread rather than calling Invoke or BeginInvoke

分享给朋友:
您可能感兴趣的文章:
随机阅读: