【问题标题】:Multiple BackGroundWorker components in a single Windows Form C#单个 Windows 窗体 C# 中的多个 BackGroundWorker 组件
【发布时间】:2015-01-16 21:36:20
【问题描述】:

在讨论我的问题之前,我想了解一下我的阶段。我对 C# 编程非常陌生。这是我第一次为此工作。所以我对 C# 的了解非常少。

我正在使用 C# 中的 Windows 窗体开发我的应用程序。在某个时刻,我应该同时运行 5 个操作。所以我尝试了 C# 工具箱中的BackGroundWorker 组件。

但是使用它,我只能处理 5 个操作中的一个。我尝试使用工具箱中的 5 个 BackGroundWorker 组件并分别定义了 DoWork 函数。

但是当我调用RunWorkerAsync() 函数时,它抛出了一个错误,说“backgroundworker is currently busy and cannot run multiple tasks concurrently”。

我不知道是否可以在我的程序中使用多个BackGroundWorker。创建数组对我没有帮助。因为我有一个无限循环要在BackGroundWorker 组件的DoWork 函数中运行。如果有任何其他方法可以同时运行 5 个操作,请帮我了解一下。提前致谢。

这是我的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;


namespace myapp5
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            bw.WorkerSupportsCancellation = true;
            bw.WorkerReportsProgress = true;

            bw.DoWork += new DoWorkEventHandler(bw_DoWork);

            bw1.WorkerSupportsCancellation = true;
            bw1.WorkerReportsProgress = true;

            bw1.DoWork += new DoWorkEventHandler(bw1_DoWork);
        }

        BackgroundWorker bw = new BackgroundWorker();
        BackgroundWorker bw1 = new BackgroundWorker();
        private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            if ((worker.CancellationPending == true))
            {
                e.Cancel = true;
            }
            else
            {
                try
                {
                    videostream();
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message);
                }
            }
        }
        private void bw1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            if ((worker.CancellationPending == true))
            {
                e.Cancel = true;
            }
            else
            {
                try
                {
                    videostream();
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message);
                }
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {

            if (bw.IsBusy != true)
            {
                bw.RunWorkerAsync();
            }
            else
            {
                MessageBox.Show("Background Worker is busy");
            }
        }
        private void button3_Click(object sender, EventArgs e)
        {
            if (bw.WorkerSupportsCancellation == true)
            {
                bw.CancelAsync();
                bw.Dispose();
                MessageBox.Show("Background Closed");
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (bw1.IsBusy != true)
            {
                bw1.RunWorkerAsync();
            }
            else
            {
                MessageBox.Show("Background Worker is busy");
            }
        }
        private void button5_Click(object sender, EventArgs e)
        {
            if (bw1.WorkerSupportsCancellation == true)
            {
                bw1.CancelAsync();
                bw1.Dispose();
                MessageBox.Show("Background Closed");
            }
        }
    }
}

【问题讨论】:

  • 你使用的是同一个 BackgroundWorker 实例吗?
  • Agree。当工作人员仍然很忙时,您无法运行其他工作,请使用 另一个 工作人员。
  • 不,我正在使用 BackgroundWorker 的不同对象,即 bw、bw1、bw2... 等,并使用不同的对象名称调用 RunWorker 函数。 @史蒂夫
  • 另一个是什么意思?你想让我使用另一个对象吗?如果是这样,我已经做到了。我仍然无法实现它。 @kennyzx
  • 那么如果您发布您的实际代码将会很有用。也许只是启动工作线程的行

标签: c# .net backgroundworker


【解决方案1】:

如果您想并行执行 5 个不同的功能,而不是需要 5 个后台工作线程。一个 Backgroupwork 线程不足以并行运行 5 个不同的函数。

您也可以为此使用 TPL(taksparallel) 库来代替后台工作程序。

【讨论】:

    【解决方案2】:

    你应该试试线程的名义用途。

    private object threadUnsafeObject;
        private object locker = new object();
    
        private void RunMulitpleThread()
        {
            object pass_your_parameter_here = "";
            for (int iCount = 0; iCount < 5; iCount++)
            {
                System.Threading.Thread thread = new System.Threading.Thread(DoWork);
                thread.Start(pass_your_parameter_here);
    
            }
        }
    
        private void DoWork(object parameters)
        {
            lock (locker)
            {
                threadUnsafeObject = parameters;
            }
        }
    

    【讨论】:

    • 不要使用线程,因为它很慢......使用ThreadPool创建线程而不是直接创建线程......或使用Task ...
    • 你是对的。不过,上面的代码仅供他参考,以防他不必使用 BackgroundWorker。
    • 所以你说我不能在我的程序中使用多个 BackGroundWorker。你不是吗? @PranayRana
    • 所以你说我不能在我的程序中使用多个 BackGroundWorker。你不是吗? @RohitPrakash
    • @Dhivakarkanagaraj,您可以使用多个后台工作者,但不能同时使用同一实例。您可以创建多个后台工作者。
    【解决方案3】:

    如果您使用的是 .net 4.0 或更高版本,则应使用 Tasks。这是 .NET 框架的发展方向。我已经设置了两个小提琴供您检查。 如果您使用的是 .NET 4.0:https://dotnetfiddle.net/GUxD2j。 如果您使用的是 .NET 4.5:https://dotnetfiddle.net/NirDuU。此示例展示了 .NET 框架中引入的新 await/async 模式的使用

    【讨论】:

      【解决方案4】:

      我认为你的程序有逻辑错误,所以同一个 BackgroundWorker 实例被使用了五次来调用 RunWorkerAsync()。查看代码。

      更新

      您的 DoWork 处理程序必须如下所示:

      private void bw_DoWork(object sender, DoWorkEventArgs e)
      {
          BackgroundWorker worker = sender as BackgroundWorker;
      
          while (true)
          {
              if ((worker.CancellationPending == true))
              {
                  e.Cancel = true;
                  break;
              }
              else
              {
                  // perform work partially with short time!
                  // and break the while loop at the end
              }
          }
      }
      

      UPD-2

      不要对工作人员使用 Dispose()。

      【讨论】:

      • 我已经在@Roman Bezrabotny 上面添加了我的代码,你能看一下吗?
      • 好的,我了解您的问题。请仔细查看CancellationPending 帮助的这一部分:“此属性旨在供工作线程使用,它应定期检查 CancellationPending 并在设置为true 时中止后台操作。”
      • 看我更新的答案
      • 否则 CancelAsync() 无法完成处理程序,后台工作人员将无限忙碌。
      猜你喜欢
      • 1970-01-01
      • 2022-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多