2017-04-05 17 views
0

私は、別のスレッド内でスレッドを開始するという概念を検討しています。これは私が思いついたコードですが、これは私が現在開発している別のプログラムのバージョンの下に流されていますが、スレッドの第2レベルが正常に完了していないことがわかりました。他のスレッド内でスレッドを開始する方法

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Diagnostics; 

namespace ConsoleApplication4 
{ 
    public class SomeClassA 
    { 
     public SomeClassA(string display) 
     { 
      System.Threading.Thread.Sleep(1000); 
      Console.WriteLine(display); 
     } 
    } 

    public class MainSomeClassA 
    { 
     public List<SomeClassA> SomeClassaAList; 
     public List<Thread> ThreadList; 
     public MainSomeClassA() 
     { 
      ThreadList = new List<Thread>(); 
      SomeClassaAList = new List<SomeClassA>(); 
      for (int i = 0; i < 10; i++) 
      { 
       ThreadList.Add(new Thread(() => StartThread("Hello"))); 
      } 
      WaitComplete(); 
     } 
     public void WaitComplete() 
     { 
      bool AllThreadsAlive = true; 
      while (AllThreadsAlive) 
      { 
       AllThreadsAlive = false; 
       foreach (Thread t in ThreadList) 
       { 
        if (t.IsAlive) 
        { 
         AllThreadsAlive = true; 
        } 
       } 
      } 
     } 
     public void StartThread(string display) 
     { 
      SomeClassaAList.Add(new SomeClassA(display)); 
     } 
    } 

    class Program 
    { 
     public static List<MainSomeClassA> MainSomeClassAList = new List<MainSomeClassA>(); 
     static void Main(string[] args) 
     { 

      Stopwatch sw = new Stopwatch(); 
      MainSomeClassAList = new List<MainSomeClassA>(); 
      List<Thread> ThreadList = new List<Thread>(); 
      bool threadsAlive = true; 
      sw.Reset(); 
      sw.Start(); 
      for (int i = 0; i < 10; i++) 
      { 
       Thread t = new Thread(AddToMainClassAList); 
       t.Start(); 
       ThreadList.Add(t); 
      } 
      while (threadsAlive) 
      { 
       threadsAlive = false; 
       foreach (Thread t in ThreadList) 
       { 
        if (t.IsAlive) 
        { 
         threadsAlive = true; 
        } 
       } 
      } 
      sw.Stop(); 
      Console.WriteLine("Elapsed Time: {0}", sw.ElapsedMilliseconds); 
      Console.ReadKey(); 
     } 

     public static void AddToMainClassAList() 
     { 
      MainSomeClassAList.Add(new MainSomeClassA()); 
     } 

    } 
} 

上記のコードでは、「hello」が表示されず、SomeClassAリストを作成せずに終了します。

答えて

1

コードの問題は、内部スレッドを開始しないことです。あなたはこのように見えるためにコンストラクタ変更し、それが動作します:言っ

public MainSomeClassA() 
{ 
    ThreadList = new List<Thread>(); 
    SomeClassaAList = new List<SomeClassA>(); 
    for (int i = 0; i < 10; i++) 
    { 
     ThreadList.Add(new Thread(() => StartThread("Hello"))); 
     // Start thread here: 
     ThreadList[ThreadList.Count - 1].Start(); 
    } 
    WaitComplete(); 
} 

が、私はあなたがプログラムがクラッシュしない幸運だということを指摘しなければなりません。 10個のスレッドが同時にMainSomeClassAListオブジェクトを変更しようとしていますが、そのうちのいくつかは必然的に内部バッファの再割り当てを強制します。つまり、リストのCountを最後に印刷すると、それは必ずしも10であるとは限りません。

実際にコードを正しく入力するには、AddToMainClassAList()メソッドのAdd()への呼び出しの周りに同期を追加する必要があります。同じことがStartThread()メソッドとSomeClassaAListオブジェクトに適用されます。

最後に、スレッドで待機する方法は非常に貧弱です。ポーリングを避けるようにしてください。この場合、Thread.Join()メソッドは合理的な選択です(スレッドをまったくブロックしないようにする必要がありますが、この例では避けられません)。たとえば、ビジーループは次のように置き換えることができます。

foreach (Thread thread in ThreadList) 
{ 
    thread.Join(); 
} 
関連する問題