2009-03-18 11 views
0

C#.NETのプログラムで、atmost 5スレッドを開始しています。しかし、時にはそれらのスレッドのいくつかは、それに割り当てられた機能の実行が完了する前であっても、単に終了したり、死んでしまうことがあります。スレッドが死んでしまうのを防ぐ方法、またはC#.NETでスレッドを終了させる方法を教えてください。

ランダムに発生します。ブレークポイントを置いてコードをデバッグしようとするとうまくいきます。

そして、すべてのスレッドが割り当てられた関数を完全に実行することがあります。それらの間でリソースを共有することはありません。

  Thread[] td = new Thread[5]; 
      for (count = 4; count >= 0; --count) 
      { 
       ds[count] = dba.getData(ru[count]); 
       td[count] = new Thread(delegate() { runRule[count].performTask(ru[count], ds[count], count); }); 
       td[count].Name = "Thread " + count.ToString(); 
       td[count].Start(); 
       Thread.Sleep(50); 
      } 

私は「のThread.sleep(50)は」最初のスレッドが実行され、それらの残りの部分はちょうど死ぬ見つめていた最後の行を削除した場合。

スレッドが死んでいる理由を説明できる人はいますか?

答えて

4

私は、彼らが死んなってきていない疑いがある - 私はこの問題は、あなたが実際にあなたがいると思うのルールを実行していないということであると思います。匿名メソッド内でメソッドのローカル変数を使用すると、変数自体が取得されます。この場合、ローカル変数countをキャプチャしてから、それを変更します(ループカウンタが減少する)。 count = 4が実行されたときに作成されるスレッドによって、countは3になる可能性があるので、runRule[3].performTask(ru[3], ds[3], 3)を呼び出します。実際にはcountに変更されましたが、表現が評価されている間に多くの楽しみをもたらす可能性があります。

これを回避する方法は、ループの繰り返しごとに異なる「ローカル」変数を持たせることです。これを行うのは簡単です:

Thread[] td = new Thread[5]; 
for (count = 4; count >= 0; --count) 
{ 
    int copy = count; 
    ds[count] = dba.getData(ru[count]); 
    td[count] = new Thread(delegate() { 
     runRule[copy].performTask(ru[copy], ds[copy], copy); 
    }); 
    td[count].Name = "Thread " + count.ToString(); 
    td[count].Start(); 
    Thread.Sleep(50); 
} 

は今、デリゲートに捕獲されている唯一の変数はcopyrunRule/ru/dsある - 私は後者の3つが変化しないと仮定しています。ループを回るたびに、copy変数の新しい「インスタンス」が作成されるため、変更は相互に干渉しません。

これが役立つかどうかを確認してください - それは以上です。少なくともは重大な混乱の原因となり、問題になる可能性があります。

+0

ThankyouForUrReply問題は、Thread.Sleep(50)の問題を避けています。メインスレッドが50ミリ秒待機すると、スレッドは次の繰り返しの前に作成されます。ここでの主な問題ではありません。5つのprgresbrを使用して、スレッドはいくつかの進捗状況を示した後に終了します。 – LoyalBanana

1

スレッドが実行パスの最後に到達すると、スレッドは自動的に終了します。あなたのexmapleでは、スレッドはperformTaskメソッドが何であれ終了します。

スレッドを永遠にハングアップさせたい場合(実際のアプリケーションで使用されていないスレッドを使用しないようにデバッグするためにのみ)、スレッドのメソッドの最後に以下のようなものを追加できますランニング。

ManualResetEvent stayAlive = new ManualResetEvent(false); 
stayAlive.WaitOne(); 
+0

私はスレッドを永遠にハングアップさせたくありません。ここでprobは完全な実行パスを完了していないということです。すべてのコードを実行する前に死んでいるか、終了しています。 – LoyalBanana

関連する問題