2

ご挨拶

クラスの複数のインスタンスを作成し、すべてのインスタンスで同じ実行時間の長い Update メソッドを実行し、完了するまで待機するプログラムがあります。Update を に追加するというこの質問から、Kev のアプローチに従っていますThreadPool.QueueUserWorkItem

メイン プログラムでは、数分間寝て、最後の子のブール値をチェックして、完了したかどうかを確認しています。

while(!child[child.Length-1].isFinished) {
    Thread.Sleep(...);
}

このソリューションは私が望むように機能していますが、これを行うためのより良い方法はありますか? 独立したインスタンスと、すべての作業が完了したかどうかの確認の両方。

ありがとう

更新: ロックする必要はありません。異なるインスタンスはそれぞれ、要求元の Web サービス URL が異なり、応答に対して同様の作業を行います。彼らは皆、自分のことをやっています。

4

4 に答える 4

1

待機のブロッキング方法は、ポーリングよりも少しエレガントです。ブロックして通知する簡単な方法については、 Monitor.Wait/ Monitor.Pulse(これも正常に動作します) を参照してください。C# には、キーワードSemaphoreの形式で Monitor クラスに関する構文糖衣があります。lock

于 2010-03-31T14:51:36.987 に答える
1

これはよく見えません。最後のスレッドが完了したときに他のスレッドも完了していると仮定する正当な理由はほとんどありません。何らかの方法でワーカー スレッドをインターロックしない限り、これは決して行うべきではありません。また、スレッドが完了するのを待つ Sleep() もほとんど意味がありません。スレッドが行っている作業を行うこともできます。

複数のスレッドが進行している場合は、それぞれに ManualResetEvent を与えます。WaitHandle.WaitAll() で完了を待つことができます。Interlocked クラスを使用したスレッド カウンターのカウント ダウンも機能します。または、CountdownLatch を使用します。

于 2010-03-31T15:18:50.353 に答える
1

実行される操作の数がわかっている場合は、カウントダウンとイベントを使用します。

Activity[] activities = GetActivities();
int remaining = activities.Length;
using (ManualResetEvent finishedEvent = new ManualResetEvent(false))
{
    foreach (Activity activity in activities)
    {
        ThreadPool.QueueUserWorkItem(s =>
        {
            activity.Run();
            if (Interlocked.Decrement(ref remaining) == 0)
                finishedEvent.Set();
        });
    }
    finishedEvent.WaitOne();
}

完了するためにポーリングしないでください。.NET Framework (および一般的な Windows OS) には、スピンロックが不要になるように特別に設計された多数のスレッド プリミティブがあり、ポーリング ループSleepは実際には低速のスピンロックにすぎません。

于 2010-03-31T14:59:25.323 に答える
1

Semaphoreを試すことができます。

于 2010-03-31T14:48:55.870 に答える