2017-04-05 521 views
0

我正在探索在另一個線程內啓動線程的概念。這是我提出的代碼,這是淡化了目前我正在開發的另一個程序的版本,但是我發現第二級線程沒有成功完成。如何在另一個線程內啓動線程

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(); 
} 
相關問題