2009-08-13 8 views
-2

私はスレッドのリストを持っている、と私は私のメインスレッドが終了するために、リスト内のすべてのスレッドを待つために取得しようとしている:リストアイテムの存在をアトミックにチェックし、リストアイテムのメソッドを呼び出す方法はありますか?

while (consumers.Count > 0) consumers[0].Join(); 

問題は、これがアトミックではありません、あり、そして私は "インデックスは範囲外"の例外を得ることができます。

コンシューマ[0]の存在を確認し、コンシューマ[0] .Join()を呼び出すためのアトミックな方法はありますか?

注:私は消費者で立ち往生参加しながら、()にアクセスする他のスレッドをブロックしたくないので、私は

lock (myLocker) { if (consumers.Count > 0) consumers[0].Join(); } 

を行うことはできません。消費者を想定し

答えて

5

を行うことができますリストが複数のスレッドから変更されている場合は、すでに問題があります。他のすべてはmyLockerを使用していますか? 、それがないと仮定する方法については:あなたは、スレッドの安全性を達成するために、どこでも何をすべきかでロックを保持しながら、このだけconsumersにアクセスすることを

while(true) 
{ 
    List<Thread> copy; 
    lock (myLocker) 
    { 
     copy = new List<Thread>(consumers); 
    } 
    if (copy.Count == 0) 
    { 
     break; 
    } 
    foreach (Thread thread in copy) 
    { 
     thread.Join(); 
    } 
} 

注意。また、反復ごとに1つずつ行うのではなく、コピーを取った後にJoinすべてと呼び出します。

あなたが(例えば、それが排水され、スレッドプールの)スレッドがこの時点でリストに追加されないことがわかっている場合は、ループチェック削除することができます:あなたのシナリオでは

List<Thread> copy; 
    lock (myLocker) 
    { 
     copy = new List<Thread>(consumers); 
    } 
    foreach (Thread thread in copy) 
    { 
     thread.Join(); 
    } 
+0

私のコピーはすぐに失効することを除いて。 スレッドが既に終了していると、thread.Join()が失敗するでしょうか? – mbeckish

+0

他のすべてのコンシューマへのアクセスは同期されます。他のコードを見れば助けになるかどうか教えてください。 – mbeckish

+2

@mbeckish:あなたのコピーはすぐに失効してしまいます。そして、Thread.Joinについてのあなたの直感は間違っています。「Joinが呼び出されたときにスレッドが既に終了していると、メソッドはすぐに戻ります。原子的に "スレッドの状態を確認して結合を呼び出す"ことができないとすれば、スレッドが既に終了している場合に例外をスローする結合APIは設計によって壊れてしまいます。 –

0

[0]は、予想される方法でのみヌルまたはクラスのインスタンスであるあなたが任意の同期は、すべてのでを適用するが、あなたの持っていない場合、あなただけまあ

while (consumers.Count > 0) 
    { 
    if (consumers[0] != null) 
     { 
     consumers[0].Join(); 
     } 
    } 
+0

カウントはチェックされた後に*リストが空になります*。 –

0

を、スレッドを待つだけのときに、なぜそのスレッド自体がリストから削除されるべきなのかを推測します。メインスレッドのみがリストからスレッドを削除できることを確認してください。このスレッドが終了すると、デザインが変更されず、存在しない要素にアクセスしないことを確認できます。あなたのループは次のようになります:


for (int i = 0; i < consumers.Count; ++i) 
    consumers[i].Join(); 
//Now that you have joined everyone, just remove reference to your list 
consumers = null; 
関連する問題