2017-04-05 518 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(); 
} 
相关问题