Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 多后台工作人员_C#_.net_Backgroundworker - Fatal编程技术网

C# 多后台工作人员

C# 多后台工作人员,c#,.net,backgroundworker,C#,.net,Backgroundworker,如何知道回路中的所有工人何时完成?以及如何“执行”bw_Runworker在所有工人都完成之后。 我试过几种方法,但都失败了。主要的工人总是先完成 .Net 3.5 使用系统; 使用系统组件模型; 使用系统线程; 命名空间控制台应用程序1 { 班级计划 { 静态void Main(字符串[]参数) { BackgroundWorker bw=新的BackgroundWorker(); bw.DoWork+=新DoWorkEventHandler(bw_DoWork); bw.RunWorker

如何知道回路中的所有工人何时完成?以及如何“执行”bw_Runworker在所有工人都完成之后。 我试过几种方法,但都失败了。主要的工人总是先完成

.Net 3.5

使用系统;
使用系统组件模型;
使用系统线程;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
BackgroundWorker bw=新的BackgroundWorker();
bw.DoWork+=新DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(bw\u RunWorkerCompleted);
bw.workersupport扫描单元=真;
bw.WorkerReportsProgress=true;
RunWorkerAsync();
Console.ReadLine();
}
静态void bw_RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e)
{
控制台。写入线(“全部”);
}
静态void bw_DoWork(对象发送方,DoWorkEventArgs e)
{
对于(int i=0;i<10;i++)
{
BackgroundWorker inBW=新的BackgroundWorker();
inBW.DoWork+=新的DoWorkEventHandler(inBW\U DoWork);
inBW.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(inBW\u RunWorkerCompleted);
inBW.RunWorkerAsync(i.ToString());
}
}
RunWorkerCompleted中的静态无效(对象发送方,RunWorkerCompletedEventArgs e)
{
Console.WriteLine(例如,结果为字符串);
}
工作中的静态无效(对象发送方,工作目标)
{
Sleep(newrandom().Next(10005000));
e、 结果=e.参数作为字符串;
}
}
}

像Steve建议的那样,使用Task。但是如果您没有自由,那么为每个子工作进程创建一个等待句柄,并在主bg工作进程中等待所有子工作进程

您需要有一个ManualResetEvents列表/数组作为成员变量,并为每个子工作者传递一个。一旦事件完成,每个子工作人员将发出一个信号。只有在接收到所有信号后,主bg工作程序才会完成(使用WaitAll


请参阅此-

一旦DoWork事件处理程序返回,就会调用RunWorkerCompleted事件处理程序。在本例中,bw_DoWork方法在派生出10个额外的BackgroundWorker后返回


我本打算建议您在您的案例中使用倒计时事件,但意识到您使用的是.NET3.5。在这种情况下,您可以使用创建类似的内容。

从异步操作中启动异步操作对我来说似乎毫无意义。毕竟,对我来说,拥有异步操作的唯一/主要原因是保持UI的响应性。在这种情况下,.Net Framework V4可以在Task类的帮助下提供很大帮助。你能移到这个版本或更高版本吗?我已经编辑了你的标题。请参阅“”,其中的共识是“不,他们不应该”。谢谢,这也是我的想法,但我需要运行bw_RunWorkerCompleted中的一些代码,当所有工作人员都完成时。这段代码只是一个例子,在现实中,我有更多的代码:)我已经更新到包括所有工人。是否有一个特定的顺序,你试图实现?它与倒计时事件。但这是一个好的解决方案吗?(因为您删除了您的评论)。我编辑了我的答案,以获得针对.net 3.5的解决方案。我认为使用单个信令对象比使用@Makubex建议的手动重置事件列表更容易管理。请注意,后台工作人员在完成的事件中封送到UI线程,这将同步所有这些处理程序的执行。因为它们已经同步了,所以您可以只使用一个简单的计数器,而不必担心争用条件。在这种情况下,您需要不断检查计数器是否已达到指定的计数以关闭主辅助进程。依我看,浪费了CPU周期。
using System;
using System.ComponentModel;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            BackgroundWorker bw = new BackgroundWorker();
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
            bw.WorkerSupportsCancellation = true;
            bw.WorkerReportsProgress = true;

            bw.RunWorkerAsync();

            Console.ReadLine();

        }

        static void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Console.WriteLine("All");
        }

        static void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                BackgroundWorker inBW = new BackgroundWorker();
                inBW.DoWork += new DoWorkEventHandler(inBW_DoWork);
                inBW.RunWorkerCompleted += new RunWorkerCompletedEventHandler(inBW_RunWorkerCompleted);

                inBW.RunWorkerAsync(i.ToString());
            }
        }

        static void inBW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Console.WriteLine(e.Result as String);
        }

        static void inBW_DoWork(object sender, DoWorkEventArgs e)
        {
            Thread.Sleep(new Random().Next(1000, 5000));

            e.Result = e.Argument as string;
        }
    }
}
static int workerCount = 11; // one more for the main BW
static int completedWorkerCount = 0;

static void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    Console.WriteLine("All");
    updateAllWorkersProgress()
}

static void inBW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
     Console.WriteLine(e.Result as String);
     updateAllWorkersProgress();
}

static void updateAllWorkersProgress()
{
     if (++completedWorkerCount == workerCount)
     {
           Console.WriteLine("Everything completed");
     }
}