简体   繁体   English

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

[英]c# calling backgroundWorker from another thread than UI thread

I'm trying to load loadingForm like below code. 我正在尝试像下面的代码一样加载loadingForm But it doesn't work, the loadingForm doesn't disappear, the event RunWorkerCompleted doesn't get called. 但它不起作用,loadForm不会消失, RunWorkerCompleted事件不会被调用。

And also, I need to call loadingForm and backgroundWorker multiple times, so how do I completely dispose the loadingForm and the backgroundWorker after each call? 而且,我需要多次调用loadingFormbackgroundWorker ,那么如何在每次调用后完全处理loadingFormbackgroundWorker

I think that there're many things wrong in my code but I don't know how to fix it. 我认为我的代码中有很多问题,但我不知道如何修复它。 Could you show me how to solve my problem and point out where I need to fix? 你能告诉我如何解决我的问题并指出我需要修复的地方吗? Thanks a lot in advance. 非常感谢提前。

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

There's a lot of things wrong with your code. 你的代码有很多问题。 If you can, try to take a step back and describe what exactly you want to do. 如果可以,请尝试后退并描述您想要做什么。

BackgroundWorker uses the Event-based Asynchronous Pattern (EAP). BackgroundWorker使用基于事件的异步模式(EAP)。 As such, it requires a thread context in which to live. 因此,它需要一个生存的线程上下文。 UI threads satisfy this requirement, but manually-created Thread instances do not (unless you install one or make the instance a secondary UI thread). UI线程满足此要求,但手动创建的Thread实例不会(除非您安装一个或使实例成为辅助UI线程)。

Similarly, UI components bind to a particular thread. 类似地,UI组件绑定到特定线程。 They require an STA thread that does message pumping (eg, Application.DoEvents ). 它们需要一个执行消息抽取的STA线程(例如, Application.DoEvents )。

It looks to me like you're creating a manual Thread and then creating UI components from that thread (so you know that the thread should be STA and include a message pumping loop, neither of which are in your code). 在我看来,你正在创建一个手动Thread ,然后从该线程创建UI组件(所以你知道该线程应该是STA 包含一个消息循环,这些都不在你的代码中)。 Then that thread starts a BGW which does message pumping. 然后该线程启动一个消息泵送的BGW。

It's not clear what you're trying to accomplish here - maybe displaying a dialog in a separate thread? 目前还不清楚你要在这里完成什么 - 也许在一个单独的线程中显示一个对话框?

Multiple UI threads in a WinForms app is not an officially supported scenario AFAIK, though some people have gotten it working. WinForms应用程序中的多个UI线程不是官方支持的场景AFAIK,尽管有些人已经开始工作。 I've never seen a need for it, though. 不过,我从未见过需要它。

According to what you have shown (which is admittedly incomplete, so this may not be the problem), you are not hooking up your event to the backgroundWorker_DoWork and backgroundWorker_RunWorkerCompleted event handlers. 根据您所显示的内容(这是不完整的,所以这可能不是问题),您不是将事件连接到backgroundWorker_DoWorkbackgroundWorker_RunWorkerCompleted事件处理程序。 Somewhere (after you instantiate your backgroundWorker ), you should have this: 某处(在实例化你的backgroundWorker ),你应该这样:

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

As a disclaimer, this was written by hand, so the event names or EventHandler types may be incorrect. 作为免责声明,这是手写的,因此事件名称或EventHandler类型可能不正确。

i really don't know how to fix your code definitively, or if your code even works the way you have it, i can only give you the following guidance. 我真的不知道如何明确地修改你的代码,或者如果你的代码甚至以你的方式工作,我只能给你以下的指导。

  1. use CancellationPending property of background worker, not the IsBusy property 使用后台工作程序的CancellationPending属性,而不是IsBusy属性
  2. when working with windows forms and threaded code, always use the Invoke / BeginInvoke methods to make sure you marshal your call back to the thread that the control originated from. 使用Windows窗体和线程代码时,请始终使用Invoke / BeginInvoke方法确保将调用 送回控件所源自的线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM