2012-02-08 14 views
0

私は、たくさんのレコードを取得し、それぞれのレコードを処理する必要のあるWebサービスを持っています。この処理は各行ごとに時間がかかる可能性があり、コードのこの部分をスレッド化して実行しています。行のデータをパラメータとして関数に渡します。私は1000以上の行を処理することができ、データ処理スレッドの数を10に制限します。スレッドを生成してWebサービス内で管理する方法は?

スレッドを監視するには、Threadオブジェクトの配列があります。私のメインスレッド(WebサービスWebMethod属性)に

Dim RowThread(9) As Thread 

私は、この配列によって新しいスレッドIループを起動し、私の次の「利用可能」スレッドを探して前に。

Dim avail_thread As Integer = -1 
While avail_thread < 0 
    For t As Integer = 0 To THREADCOUNT - 1 
     If IsNothing(RowThread(t)) OrElse Not RowThread(t).IsAlive Then 
      avail_thread = t 
      Exit For 
     End If 
    Next 
End While 

...

RowThread(avail_thread) = New Thread(New ParameterizedThreadStart(AddressOf ProcessRow)) 

...

RowThread(avail_thread).Start(row) 

あなたが見ることができるように、それはスレッドが完了するまで待機し、次の使用可能なスレッド上で次の行を起動します。 10個のスレッドがすべて使用されている場合、スレッドはループし続け、使用可能な状態になるまで待機します。

このアプローチはうまく動作し、ほとんどのサーバーでうまく動作します。最近、一部のサーバーでは、このループにある間にCPUをペグアウトするので、問題を引き起こしていることに気がつきました。これは、メインスレッドが大量のCPUサイクルを浪費しているため、全体的なパフォーマンスに影響します。これを簡単にするために、スレッドSleep()とDoEvents()を試しましたが、これらのアプローチはパフォーマンスをさらに低下させます。

誰もがこのシナリオに遭遇しましたか?私はデリゲートなどを使用することはできません。これはWebサービス内にあるため、すべての行が処理されるまで結果を送信しないようにするためにメイン呼び出しを終了したくありません。 ThreadPoolと同じ問題ですが、ThreadPoolのことはあなたにも多くの制御を与えてくれます。

Webサービス内からスレッドを確実に生成してから管理する方法はありますか。非ブロッキング手動スレッド監視を実行する方法はありますか?

+0

.NETのどのバージョンを使用していますか? .NET 4.0を使用している場合は、Parallel.ForEachを使用するようにしてください。 –

答えて

2

スレッドプールにすべての作業を投稿してみませんか?これは、あなたのために完全に正確で効率的な方法でこれを行います。適切な数のスレッドを作成し、それらの間で作業項目を配布します。 TPLのタスククラスを使用すると、タスクの完了を監視することさえできます。

+0

私はスレッドプールの使用について考えましたが、文字通り1000以上のリクエストでそれを読み込めますか?私が読んでいるデータはデータベースから来ており、私は行のデータを各スレッドに渡します。それがキューに置かれている間に、1000 +行分のデータがどこに置かれますか?おそらくメモリ、BLOBなどでデータを処理していると、枯渇したくありません。 – nullvalue

0

私はWaitHandleで答えを見つけたと思います。以前の研究では、これらをThreadPoolでのみ使用できると考えていましたが、手動で起動したスレッドでも使用できることが判明しました。

私が今使用します。

RowEvents(avail_thread) = New ManualResetEvent(False) 

その後スレッドのスタートに私のパラメータオブジェクトの一部としてこれを渡します。その関数が完了すると、そのスレッドのManualResetEventオブジェクトでSet()を実行します。彼らはすべての後、私はWAITANY方法、フォーカスを呼び出し実行している場合

Dim avail_thread As Integer = -1 
While avail_thread < 0 
    For t As Integer = 0 To THREADCOUNT - 1 
     If IsNothing(RowThread(t)) OrElse Not RowThread(t).IsAlive Then 
      avail_thread = t 
      Exit For 
     End If 
    Next 
    'All threads busy, call blocking wait 
    If avail_thread < 0 Then avail_thread = WaitHandle.WaitAny(RowEvents) 
End While 

最初のパス上のすべての10件のスレッドを通してこのう今ループ..:

は、次の使用可能なスレッドのコードは次のようになります見つけるマイいずれかのスレッドが完了すると返され、avail_thread変数が終了したインデックススレッドに設定されます。

関連する問題