c#从另一个线程调用backgroundWorker而不是UI线程

时间:2010-12-22 20:01:01

标签: c# multithreading forms backgroundworker

我正在尝试加载loadingForm,如下面的代码。但它不起作用,loadingForm不会消失,事件RunWorkerCompleted不会被调用。

此外,我需要多次致电loadingFormbackgroundWorker,那么如何在每次通话后完全处理loadingFormbackgroundWorker

我认为我的代码中存在许多错误,但我不知道如何修复它。你能告诉我如何解决我的问题并指出我需要修复的地方吗?非常感谢。

public partial class loginForm : Form
{
     //....
     private loadingForm lf;
     private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
     {
          lf.Show();
          While (backgroundWorker1.isBusy)
               Application.DoEvents();
     }
     private void backgroundWorker1_RunWorkerCompleted(object sender, DoWorkEventArgs e)
     {
          lf.Close();
     }
     private void connect()
     {
          //....
          Thread mainThread = new Thread(ThreadStart(listentoServer));
          mainThread.Start();
     }
     private void listentoServer()
     {
          //....
          lf = new loadingForm();
          backgroundWorker1.RunWorkerAsync();
          //....
          backgroundWorker1.CancelAsync();
          //.... 
     }
}

3 个答案:

答案 0 :(得分:3)

您的代码存在很多问题。如果可以,请尝试后退并描述您想要做什么。

BackgroundWorker使用基于事件的异步模式(EAP)。因此,它需要一个生存的线程上下文。 UI线程满足此要求,但手动创建的Thread实例不会(除非您安装一个实例或使实例成为辅助UI线程)。

类似地,UI组件绑定到特定线程。它们需要一个消息泵送的STA线程(例如,Application.DoEvents)。

在我看来,您正在创建一个手册Thread,然后从该线程创建UI组件(因此您知道该线程应该是STA 并且包含一个消息循环,这些都不在您的代码中)。然后该线程启动一个消息泵送的BGW。

目前还不清楚你要在这里完成什么 - 可能在一个单独的线程中显示一个对话框?

WinForms应用程序中的多个UI线程不是官方支持的场景AFAIK,尽管有些人已经开始工作了。不过,我从未见过需要它。

答案 1 :(得分:1)

根据您所显示的内容(这是不完整的,所以这可能不是问题),您不会将您的活动与backgroundWorker_DoWorkbackgroundWorker_RunWorkerCompleted事件处理程序联系起来。某处(在您实例化backgroundWorker之后),您应该拥有:

backgroundWorker.DoWork += new EventHandler(backgroundWorker_DoWork);
backgroundWorker.RunWorkerCompleted += new EventHandler(backgroundWorker_RunWorkerCompleted);

作为免责声明,这是手写的,因此事件名称或EventHandler类型可能不正确。

答案 2 :(得分:1)

我真的不知道如何明确地修改你的代码,或者如果你的代码甚至以你的方式工作,我只能给你以下的指导。

  1. 使用后台工作者的CancellationPending属性,而不是IsBusy属性
  2. 使用Windows窗体和线程代码时,请始终使用Invoke / BeginInvoke方法确保将您的调用封送回控件所源自的线程。