简体   繁体   中英

c# calling backgroundWorker from another thread than UI thread

I'm trying to load loadingForm like below code. But it doesn't work, the loadingForm doesn't disappear, the event RunWorkerCompleted doesn't get called.

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?

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). 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).

Similarly, UI components bind to a particular thread. They require an STA thread that does message pumping (eg, 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). Then that thread starts a BGW which does message pumping.

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. 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. Somewhere (after you instantiate your backgroundWorker ), you should have this:

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.

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
  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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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