2009-08-03 18 views
2

オブジェクトを作成するコンソールテストアプリケーションを作成しました。&オブジェクトは2つの独立したスレッドで2つの関数を呼び出します。 1つのスレッドは、1から20の数字を逆の順序でもう一方の数字の形で印刷します。メインスレッドのデバッグ時にワーカースレッドが実行されないのはなぜですか?

問題は、メインスレッドのデバッグを停止しない(つまりf5を押す)まで、最初のワーカースレッドがデバッグされないという問題です。答えは?

class Program 
{ 
    static void Main(string[] args) 
    { 
    DisplayData dd = new DisplayData(); 

    ThreadStart ts1 = new ThreadStart(dd.DisplayNumber); 
    Thread t1 = new Thread(ts1); 
    t1.Name = "Display Numbers"; 

    ThreadStart ts2 = new ThreadStart(dd.ReverseNumbers); 
    Thread t2 = new Thread(ts2); 
    t2.Name = "Reverse Numbers"; 

    t1.Start(); //Keep 1st break point at this location. Then press F10. 
    t2.Start(); //Keep break point at this location permanently 
    } 




public class DisplayData 
    { 
     public void DisplayNumber() 
     { 
      int length = 20; 
      Console.WriteLine("\nNumbers in correct order.\n"); 


      for (int i = 0; i < length; i++) 
      { 

      Console.WriteLine("DN: The value of i is: " + (i+1) + " " + Thread.CurrentThread.ManagedThreadId + " " + Thread.CurrentThread.Name); 
      //Thread.Sleep(1000); 

      } 
     } 

     public void ReverseNumbers() 
     { 
      int length = 20; 
      Console.WriteLine("\nNumbers in reverse order.\n"); 
      for (int i = 0; i < length; i++) 
      { 

      Console.WriteLine("RN: The value of i is: " + (length - i) + " " + Thread.CurrentThread.ManagedThreadId + " " + Thread.CurrentThread.Name); 
      //Thread.Sleep(1000); 
      } 
     } 
+0

sDisplayNumberとReverseNumbersはどのように見えますか? –

+0

1つの問題は、t2.Start()に降りると、スレッドが開始されたときを正確に保証するものではなく、t1がまだ開始していない可能性がありますが、その行を一時停止しているため何も起こりません。 t1.Start()とt2.Start()の間に行を置くと、スレッドが起動したかどうかを確認してから、t2を起動するとうまくいくでしょう。 –

+0

t1.Start()とt2.Start(0からt1が実行される)の間にConsole.ReadKey()を置くと、 –

答えて

6

これはVisual StudioまたはCLRの制限事項ですが、あるスレッドのブレークポイントを設定するとすべてのスレッドが停止するかどうかはわかりません。

スレッドを一時停止したい場合は、Debug..Threadsウィンドウでこれを行うことができます。そこでは、スレッドを一時停止してから再開することができます。

+4

個人的には、ブレークポイントを設定するとすべてのスレッドが壊れるという制限はないと思います。マルチスレッドコードをデバッグすると –

+0

私はスレッドウィンドウに移動する - >メインスレッドをフリーズし、f5を押すとスレッドt1が実行されますが、メインスレッドを再開する方法はありませんスレッドウィンドウのフォーカスが外れる(ブレークポイントが抜け出てから空白になります) これはVBSStudioがデフォルトですべてのスレッドを一時停止することを示しています; Andrew氏はデバッグ目的には良いと述べています。 –

+0

この制限は、あなたが突然スレッドを分割して各スレッドの状況を確認したいと思っていれば良いと思います。任意のスレッドで条件を破りたいとします。今、他のスレッドが実行し続けている場合、その時点でプログラムのスナップショットビューを取得するにはどうすればいいですか?とにかく、自分の意志でスレッドをフリーズ/解凍することができます(中断した後は一度)。自然なデバッグフローには適しています。 –

2

他の脅威への対応は、コンテキストの切り替えが発生するまで開始されません。 CPUが何か他のもので始めることを決める前に、メインルーチンのすべての作業を簡単に行うことができます。

t1.Join()を使用すると、作業スレッドが終了するまで待ってから続行します。

1

メインスレッドコードを踏み続けると、最終的にワーカースレッドの1つに切り替わります。それはあなたが特にデバッグに何をしたいかどう

しかし、あなたの状況に最も簡単な方法は、 ディスプレイ番号 ReverseNumbersの最初の行にブレークポイントを配置することです。

+0

問題は、スレッディングの仕組みを理解しようとしていたことです。したがって、単純な例です。 –

1

「実行」しますが、必ずしもタイムスライスを取得する必要はありません。コードを一歩一歩進めると、すべてのスレッドが効果的に「実行」されます。ただし、実行中のスレッドの実際の数は使用可能なCPUによって異なります。状況によっては、他のスレッドが実行される場合と実行されない場合があります。

.NETフレームワークは標準出力にアクセスを同期させるため、いつでも一方のスレッドだけがそのロックを保持します。これにより、他のスレッドが実行されないという印象を与えることができます。

+0

別の可能性。 –

関連する問題