C#从UI线程之外的另一个线程调用backgroundWorker

发布于 2024-10-09 07:32:37 字数 1149 浏览 0 评论 0原文

我正在尝试像下面的代码一样加载 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();
          //.... 
     }
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一梦浮鱼 2024-10-16 07:32:37

你的代码有很多问题。如果可以的话,试着退后一步,描述一下你到底想做什么。

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

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

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

目前尚不清楚您要在这里完成什么 - 也许在单独的线程中显示一个对话框?

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

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 (e.g., 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.

诠释孤独 2024-10-16 07:32:37

根据您所显示的内容(这确实不完整,因此这可能不是问题),您没有将事件连接到 backgroundWorker_DoWorkbackgroundWorker_RunWorkerCompleted 事件处理程序。在某个地方(在实例化 backgroundWorker 之后),您应该具有以下内容:

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

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

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.

枫林﹌晚霞¤ 2024-10-16 07:32:37

我真的不知道如何最终修复您的代码,或者如果您的代码甚至按照您的方式工作,我只能为您提供以下指导。

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

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文