【问题标题】:BackgroundWorker does not fire the RunWorkerCompleted eventBackgroundWorker 不会触发 RunWorkerCompleted 事件
【发布时间】:2011-07-13 09:25:52
【问题描述】:

我不是在我的 Windows 窗体中创建后台工作程序,而是在实现所有处理的类文件 (BusinessLogic) 中。在主窗体中,我首先调用初始化 BGW 的 BL 方法。然后我调用 BL 的方法来启动 BGW。

这里有更多关于我的实现的背景:)。 How to use BackGroundWorker in class file?

DoWork 事件运行良好,但没有调用 RunWorkerCompleted。

一些谷歌搜索,我发现了这个链接。我有一种感觉,我的问题和这些家伙一样。 http://www.eggheadcafe.com/software/aspnet/29191764/backgroundworker-does-not-fire-the-runworkercompleted-event.aspx

如果您能就此问题提供任何意见,我将不胜感激。提前致谢。

主格式代码:

    private void frmMain_Load(object sender, EventArgs e)
    {
      Hide();
      BusinessLogic.BGWInitialize();
      BusinessLogic.StartBackgroundWorker();                
      while (!BusinessLogic.firstCycleDone)
      {
        Thread.Sleep(100);
      }
      Show();            
    }        

BusinessLogic 中的代码:

    public static void BGWInitialize()
    {
        bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
        bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged);
        bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
        bgWorker.WorkerReportsProgress = true;
    }

    public static void StartBackgroundWorker()
    { 
        bgWorker.RunWorkerAsync();
    }


    private static void bgWorker_RunWorkerCompleted(
        object sender, RunWorkerCompletedEventArgs e)
    {            
        firstCycleDone = true;             

    }

【问题讨论】:

  • (有点跑题了)我不得不假设这不是你要上线的代码,但以防万一,你为什么要找一个新的 BG线程来完成工作,然后在调用线程上调用 Thread.Sleep()?为什么不同步地完成工作?
  • 嗯,是的,我刚刚发现了这一点。 :) 我在我的应用程序中跨多个表单执行此操作(调用 BGW),并默认在主表单中实现它。但是主窗体不需要 BGW,因为我希望应用程序仅在处理完成后打开。

标签: c# .net backgroundworker


【解决方案1】:

完成的事件被调用到主线程。它应该由 MessagePump 拾取并执行。

但是,您的 Wait-and-Sleep 代码阻塞了消息循环。

  Hide();
  ....
  while (!BusinessLogic.firstCycleDone)
  {
    Thread.Sleep(100);
  }
  Show();

这里的答案是你没有使用 Backgroundworker 或其他形式的线程...

直接拨打bgWorker_DoWork()即可:

 // Hide();
 bgWorker_DoWork();  // rename
 Show();  

【讨论】:

  • 或者如果你因为某种原因确实想阻塞主线程,在你的工作例程退出之前设置标志。
  • 感谢您解决了问题。是的,使用线程然后停止主线程直到工作线程完成处理,这对我来说非常愚蠢。在我的辩护中,我在我的应用程序中以多种形式使用 BGW,这是我需要等待处理完成的唯一实例。所以我只是在这里复制粘贴了我的其他代码,并认为在这种情况下不需要它。
  • @HenkHolterman 我的主线程正在等待 RunWorkerCompleted 应该释放的信号量,这导致了死锁。如何在确保可以调用 RunWorkerCompleted 的同时等待主线程?
  • @Omtara - 将其作为一个单独的问题(在查找重复项之后)
【解决方案2】:

如果您只调用Application.DoEvents(); 而不是Sleep(100);,您的代码就可以工作,但正如我之前所说,BackgroundWorker 类是一个错误的东西,我会亲自使用我自己的线程和报告

或者你也可以睡一会,然后打电话给DoEvents

【讨论】:

  • 后台工作人员没有问题。但是大多数使用 Application.DoEvents() 的程序都是。
  • 我并没有说它是一个完美的解决方案,而且根据我的经验BackgroundWorker 是错误的。我能有自己的看法吗?
  • 仅当您备份它(示例/链接)
猜你喜欢
  • 1970-01-01
  • 2011-02-17
  • 2011-11-29
  • 1970-01-01
  • 2023-04-08
  • 2011-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多