c# - 了解 BackgroundWorker

标签 c# for-loop backgroundworker

我想了解如何使用 BackgroundWorker。 我试图将它分解为一个控制台 C# 项目,实际上它是一个 Windows 窗体应用程序,其中一个按钮触发三个后台任务的执行。当按钮被按下时,它应该被禁用以防止进一步的按钮事件。当所有三个任务都完成后,该按钮应该再次启用。也应该在主线程中测试这三个任务是否成功。为了防止将这一切混合到 Forms 应用程序中,我现在正在尝试了解基础知识并将其移至 Forms 应用程序。 (从评论设置你可能猜到我理解的问题在哪里) 考虑这个(仍然错误的)代码:

using System;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;

namespace BGWorkerConsoleApp
{
    class Program
    {

//        #region BackgroundWorker
//
private System.ComponentModel.BackgroundWorker worker = new System.ComponentModel.BackgroundWorker();

//
//        #endregion
        static void Main(string[] args)
        {
//            BackgroundWorker worker = new System.ComponentModel.BackgroundWorker();

            worker.RunWorkerCompleted += TestComplete;
            worker.DoWork += TestConnection1;
//            worker.DoWork += TestConnection2;
//            worker.DoWork += TestConnection3;
            DoWorkEventArgs e = new DoWorkEventArgs(); // ???

            worker.RunWorkerAsync(e); // ???
        }

        private void TestConnection1(object sender, DoWorkEventArgs e)
        {
            bool success = false;
            Thread.Sleep(14000); // stands for some time consuming Task
            success = true;
            e.Result = success;
        }
        private void TestConnection2(object sender, DoWorkEventArgs e)
        {
            bool success = false;
            Thread.Sleep(10000); // stands for some time consuming Task
            success = true;
            e.Result = success;
        }
        private void TestConnection3(object sender, DoWorkEventArgs e)
        {
            bool success = false;
            Thread.Sleep(5000); // stands for some time consuming Task
            success = true;
            e.Result = success;
        }

        private void TestComplete(object sender, RunWorkerCompletedEventArgs e)
        {
            Console.WriteLine("complete");
        }

    }
}

我的问题:

我可以向 BackgroundWorker 添加多个任务吗?可能不是,因为只有一个 RunWorkerAsync。假设每项任务都需要一个工作人员,我将如何等待所有三个任务完成?

好的,让我将其更改为 Forms 应用程序,因为压力并不在于在控制台应用程序中运行 BackGroundworker,而是我想了解如何为多个 BackGroundWorker 设计应用程序并等待它们完成(包括参数和结果的传递和返回。

这是表单应用程序中的相同代码:

using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.Threading;

namespace BackGroundWorkerForm
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;


        private Button button;
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.Text = "Form1";
            button = new System.Windows.Forms.Button();
            button.Location = new System.Drawing.Point(100, 10);
            button.Name = "button";
            button.Size = new System.Drawing.Size(100, 20);
            button.TabIndex = 5;
            button.Text = "TestConnection";
            button.Click += new System.EventHandler(this.RunTest);
            button.Visible = true;
            Controls.Add(button);
        }

        #endregion


       private void RunTest(object o, EventArgs e)
        {
        BackgroundWorker worker = new System.ComponentModel.BackgroundWorker();
        worker.RunWorkerCompleted += TestComplete;
        worker.DoWork += TestConnection1;
//            worker.DoWork += TestConnection2;
//            worker.DoWork += TestConnection3;

        worker.RunWorkerAsync();
        }   
        private void TestConnection1(object sender, DoWorkEventArgs e)
        {
            bool success = false;
            Thread.Sleep(10000); // stands for some time consuming Task
            success = true;
            e.Result = success;
        }
        private void TestConnection2(object sender, DoWorkEventArgs e)
        {
            bool success = false;
            Thread.Sleep(10000); // stands for some time consuming Task
            success = true;
            e.Result = success;
        }
        private void TestConnection3(object sender, DoWorkEventArgs e)
        {
            bool success = false;
            Thread.Sleep(10000); // stands for some time consuming Task
            success = true;
            e.Result = success;
        }

        private void TestComplete(object sender, RunWorkerCompletedEventArgs e)
        {
            button.Text= "complete";
        }

    }
}

最佳答案

这是一个使用 Tasks 而不是后台 worker 的例子。 每个 Task 都是异步启动的,然后等待所有任务是否成功完成,然后再处理结果。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace BGWorkerConsoleApp
{
    class Program
    {
        static Stopwatch sw = new Stopwatch();
        static void Main(string[] args)
        {
            // parse your args
            int[] parsedargs = { 1400, 1000, 500 };
            int count = 0; // to provide task count
            List<Task> tasks = new List<Task>();
            sw.Start(); //stopwatch for some to verify the time
            foreach (int i in parsedargs)
            {
                // start a task for each
                tasks.Add(Task.Factory.StartNew<bool>(
                    () => { return myTask(i, String.Format("Task{0} done.  ", ++count)); } ) );
            }

            // wait for all the tasks to complete
            Task.WaitAll(tasks.ToArray());

            // check the response of each
            bool faulted = false;
            foreach (Task<bool> t in tasks)
            {
                if (t.Result == false)
                {
                    faulted = true;
                    break; //there was a problem so quit looking
                }
            }

            //output some text
            if (faulted)
            {
                Console.WriteLine("There was a problem.");
            }
            else
                Console.WriteLine("complete");

            // pause so we can see our output in the debugger
            Console.ReadKey();
        }

        static bool myTask(int time, string msg)
        {
            Thread.Sleep(time);
            if (time == 1000)
                return false; 
            Console.WriteLine(msg + printStopWatchTime());
            return true;
        }

        static string printStopWatchTime()
        {
            TimeSpan ts = sw.Elapsed;
            string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
            ts.Hours, ts.Minutes, ts.Seconds,
            ts.Milliseconds / 10);
            return string.Format("RunTime {0}", elapsedTime);
        }
    }
} 

关于c# - 了解 BackgroundWorker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22458498/

相关文章:

arrays - Swift:检测字符串的首字母何时不等于特定字符?

带有动态div id的javascript for循环

wpf - 如何在BackgroundWorker中创建WPF窗口?

.NET Backgroundworker - 有没有办法让异常正常传递回主线程?

c# - 带有 nameof 运算符的方法链

c# - 如何以编程方式构造对象引用?

c# - 事件日志实用性

algorithm - N 嵌套 for 循环

c# - SQLite 数据库与 C# 执行速度非常慢

c# - 另一个后台 worker