0

スレッドのグループ全体の処理が完了したことを検出するためのベスト プラクティスは何ですか? [長時間実行] Web サービスに任意の数のオブジェクトを照会し、それらすべてが正常に完了したときにトランザクション アクションを実行する必要があるプロセスがあります。現在、.Net スレッド プールのデリゲートを使用して、それらを非同期で実行しています。それらを同期的に実行すると、複数のスレッドで実行する目的が無効になります...すべてが終了したことを他にどのように検出できますか? 私はカウンター(別名COM参照カウント)を使用して、開始するスレッドに到達するためにそれをインクリメントし、コールバック関数でそれをデクリメントし、各スレッドへの参照を含む動的リストを保持して、それぞれを明示的に追跡することを考えましたそれらが完了すると、しかし、これらのソリューションはどちらもちょっとぎこちないようです...

すべてのおかげで... yr の提案に基づいて、オブジェクト インスタンスを非同期スレッド (以下の ref 変数 uPL で表される) に渡す必要があるため、次のコードを使用しています... 注: IEEDAL.GetUsagePayloadReadings(uPL1)リモート Web サービス呼び出しです

    foreach (MeterChannel chgChan in chgChs)
        foreach (UsagePayload uPL in chgChan.IntervalPayloads)
        {
            ManualResetEvent txEvnt = new ManualResetEvent(false);
            UsagePayload uPL1 = uPL;
            ThreadPool.QueueUserWorkItem(
                delegate(object state)
                    {
                        if (!uPL1.HasData)
                            IEEDAL.GetUsagePayloadReadings(uPL1);
                        UsageCache.PersistPayload(uPL1);
                        SavePayLoadToProcessFolder(uPL1);
                        txEvnt.Set();
                    } );
            waitHndls.Add(txEvnt);
        }
    WaitHandle.WaitAll(waitHndls.ToArray());
4

5 に答える 5

3

これを行うために私が見た最良の方法は、カウントダウン ラッチを使用することです。MSDN Magazine の 2007 年 5 月号には、C# のソースを含む非常に優れた説明があります。

于 2009-03-16T15:39:59.453 に答える
3

WaitHandle.WaitAllを使用できます。

于 2009-03-16T14:15:14.917 に答える
2

いくつかのオプションがあります。

セマフォを使用すると、すべてのスレッドでカウンターを使用できます。正確な数がわかっている場合は、これを使用していつ完了したかを確認できます。

別の可能な代替手段は、スレッドごとに ResetEvent を持つことです。スレッドの「最後」にイベントを設定し、メインスレッドで確認してください。ただし、これはより難しい場合があります。

于 2009-03-16T14:14:42.407 に答える
1
Dim WaitAllEvents(1) As AutoResetEvent

Dim thread1 As Thread
Dim thread2 As Thread

thread1 = New Thread(AddressOf Thread1Worker)
thread2 = New Thread(AddressOf Thread2Worker)

WaitAllEvents(0) = New AutoResetEvent(False)
WaitAllEvents(1) = New AutoResetEvent(False)

thread1.Start()
thread2.Start()

'Main thread will wait until all instances of AutoResetEvent 
'have become signaled with a call to Set()

WaitHandle.WaitAll(WaitAllEvents)

Console.WriteLine("All threads done exiting main thread")
thread2 = Nothing
thread1 = Nothing

'...
'...

Private Sub Thread1Worker()
    Thread.Sleep(5000)
    Console.WriteLine("Thread1 done")
    WaitAllEvents(0).Set() 
End Sub

Private Sub Thread2Worker()
    Thread.Sleep(3000)
    Console.WriteLine("Thread2 done")
    WaitAllEvents(1).Set() 
End Sub
于 2009-03-16T14:21:41.297 に答える