【问题标题】:Run background workers sequentially按顺序运行后台工作人员
【发布时间】:2016-06-20 05:46:54
【问题描述】:

我构建了一个 C# Winforms 应用程序,用作模拟运行一组计算和内存密集型任务。我正在使用后台工作人员来完成工作,以便 UI 可以保持响应。我只有一个 for 循环:

var iterations = Convert.ToInt32(txtNumIterations.Text);
for (int i = 0; i < iterations; i++)
{
ResetSim();
StartWorker("RunSimulation", i + 1);
}

我想要的是在后台按顺序运行这些,但我不知道设置的后台工作人员是否会执行此操作,或者我是否需要使用任务。我还没有找到一个很好的例子来解释任务如何实现我的目标。任何帮助将不胜感激。

【问题讨论】:

  • 为什么不只使用一名工作人员并将for 循环放入其中?
  • @ScottChamberlain,这正是我会做的。我觉得,您应该将其发布为更有意义的答案。

标签: c# winforms


【解决方案1】:

您可以在 DoWork 方法中使用BackgroundWorker.ReportProgress Method 将信息传回主线程。您可以在 DoWork 方法中执行循环,并在每个循环调用 worker.ReportProgress(i); 时使用循环变量。该值不由后台工作人员解释,因此它不需要是百分比值。然后在ProgressChanged 事件处理程序中,您可以调用ResetSim();。 (我假设ResetSim 在 UI 中起作用,因此必须在 UI 线程上执行。)

【讨论】:

    【解决方案2】:

    如果您需要按顺序运行模拟,则可以订阅后台工作人员RunWorkerCompleted 事件以开始下一个。

    所以你只需启动第一个工人:

    var worker1 = new BackgroundWorker();
    worker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
    worker1.RunWorkerAsync();
    

    然后在处理程序中:

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        var worker2 = new BackgroundWorker();
        worker2.RunWorkerCompleted += backgroundWorker2_RunWorkerCompleted;
        worker2.RunWorkerAsync();
    }
    

    显然,您可以使用一个数组来保存对每个工作人员的引用,并使用一个类变量来保存哪个工作人员处于活动状态。然后,您只需要一个处理程序来增加模拟计数并启动列表中的下一个处理程序。

    【讨论】:

    • 那么使用 BackGroundWorker 的意义何在。为什么不以经典的同步方式运行所有方法/操作。
    • @Rahul - 好吧,您可能希望 UI 在处理时做出响应,以便您可以执行其他任务、取消模拟等。
    【解决方案3】:

    从您的描述看来,您确实不需要多个后台工作人员,只需使用一个后台工作人员并在其中运行循环即可。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-14
      • 2023-03-16
      • 1970-01-01
      相关资源
      最近更新 更多