【问题标题】:What is the recommended way to create multiple (more than 10) BackgroundWorkers?创建多个(超过 10 个)BackgroundWorkers 的推荐方法是什么?
【发布时间】:2012-10-25 04:10:29
【问题描述】:

阅读这些BackgroundWorker vs. ThreadPool vs. Thread 提示后,我决定选择BackgroundWorker

我知道如何通过将其组件从工具箱拖放到我的表单中来创建这样一个线程,但由于我需要多个这样的线程(10-20 之间的有限数量),我不确定什么是正确的解决方法是:

  • 拖放其中的 10-20 个,在代码中为它们创建占位符,但仅启动需要运行的那些,具体取决于应用程序的需求(在不同的场景中,我可以运行这 10-2 个中的 1-2 个) 20 个线程)。

我更喜欢拖放方法,但我在 BackgroundWorker 方面没有经验,我不确定要权衡什么。

有经验的 BackgroundWorker 程序员有什么建议吗?

【问题讨论】:

  • 您是否也考虑过任务(.NET 4)?
  • 知道工人会做什么会有所帮助。
  • @ateiob 它们是由不同的用户操作引起的,还是你按一个按钮然后全部启动?
  • @ateiob 如果您正在轮询,那么它们确实应该是计时器,您担心它们是否在后台运行是正确的。有几个计时器可供选择。如果您使用 Windows.Forms.Timer,则Tick 事件在 UI 线程中运行;您需要使用异步 IO 方法,使用 async 关键字(如果您有 .NET 4.5,这将是最佳选择)或执行其他操作以移动到后台线程。或者您可以只使用任何其他计时器,因为它们的事件不会在 UI 线程中触发。
  • @ateiob 好吧,如果您将 CheckForIllegalCrossThreadCalls 设置为 false 则不,它不会总是抛出异常,它只是 可能抛出例外或无法以某种微妙的方式工作。一种简单的检查方法是只睡 5 秒钟;如果表单冻结你在 UI 线程中,如果不是你不是。如果您不是(而且您不应该),那么您需要能够编组回 UI 线程,以便在准备好时使用结果更新控件。使用Control.Invoke 来做到这一点。

标签: c# winforms backgroundworker


【解决方案1】:

您可以创建一个包含它们的数组。为每个您添加一个处理程序。完成后,通过数组来处理它们。例如(对不起,这是从VB代码翻译过来的,我不是C#专家,所以最坏的情况请视为伪代码):

//globally
List<BackgroundWorker> workers = new List<BackgroundWorker>();

//within a sub/function
int numberOfWorkersNeeded = 10;
for (i = 0; i < numberOfWorkersNeeded; i++) {
    BackgroundWorker bg = new BackgroundWorker();
    bg.DoWork += new DoWorkEventHandler(MyWorkHandler);
    bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(MyWorkFinishedHandler);
    workers.Add(bg);
}

移除(它们是可重复使用的,所以这是用于退出或不再需要工人时):

for (i = 0; i < workers.Count; i++) {
    if (!bg.IsBusy) {
        //remove handlers
        workers(i).Dispose();
    }
}

权衡如@ateiop 所述,您需要手动创建(和删除)事件处理程序。

对于BackgroundWorker,您有两个主要事件,DoWorkRunWorkerCompleted。此外,如果您想报告进度,您需要启用报告 (bg.WorkerReportsProgress = true;) 并为此添加处理程序 (ProgressChanged)。

无论如何,你还需要处理尚未完成的工人。

【讨论】:

  • +1 用于以编程方式创建 BackgroundWorkers 的实际代码示例。这也可能是公认的答案(除非出现更好的答案),但我喜欢拖放方法的原因是您可以通过双击来定义/访问其所有事件处理程序。在这里,我不确定我是否错过了什么?
  • 试图清理 vb 翻译,我忽略了什么吗?
  • @ateiob 鉴于上面的 cmets,事实上这实际上将每 X 分钟定期运行一次,它会相当大地改变答案。
  • @AbdiasSoftware 想知道您是否要将其从索引的 1 更改为索引的 0 for 循环;)-我也觉得很奇怪,您在 i 之外声明 for 循环,这……不寻常。
  • 好吧,麻烦你了。我确实提供了一个例子。我认为这足以让 OP 继续前进,同意吗? :-)
猜你喜欢
  • 2014-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-28
  • 1970-01-01
  • 2018-09-06
  • 2011-02-16
  • 2023-02-26
相关资源
最近更新 更多