0

ループからのすべてのワーカーがいつ終了したかを知る方法は? そして、すべてのワーカーの後に bw_RunWorkerCompleted を「実行」する方法。私はいくつかの方法で試しましたが、失敗しました。メインワーカーは常に最初に終了します。

.Net 3.5

http://pastebin.com/kMmajq6f

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;
        }
    }
}
4

3 に答える 3

3
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");
     }
}
于 2012-09-26T15:24:03.710 に答える
2

RunWorkerCompletedイベントハンドラーは、DoWorkイベントハンドラーが戻ると呼び出されます。この場合、bw_DoWorkメソッドは、10個の追加のBackgroundWorkersをスピンオフすると戻ります。

ケースにCountdownEventを使用することをお勧めしましたが、.Net3.5を使用していることに気付きました。その場合、PulseとWaitを使用して同様の何かを作成できます。

于 2012-09-26T15:37:36.357 に答える
2

Steve が提案したように、Task を使用します。しかし、自由がない場合は、サブワーカーごとに待機ハンドルを作成し、メインの bg ワーカーでそれらすべてを待機します。

メンバー変数としてManualResetEventsのリスト/配列を用意し、サブワーカーごとに 1 つ渡す必要があります。各サブワーカーは、完了するとイベントを通知します。メインの bg-worker は、すべてのシグナルが受信された後にのみ完了します ( WaitAllを使用します) 。

これを参照してください-MSDNの手動リセットイベントとWaitAll

于 2012-09-26T15:32:47.300 に答える