繁体   English   中英

如何在另一个线程中启动一个线程

[英]How to start a thread within another thread

我正在探索在另一个线程中启动一个线程的概念。 这是我想出的代码,这是我当前正在开发的另一个程序的精简版本,但是我发现第二级线程无法成功完成。

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列表的情况下退出。

代码的问题在于,您永远不会启动内部线程。 更改您的构造函数,使其看起来像这样,它将起作用:

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();
}

就是说,我应该指出,您很幸运该程序没有崩溃。 您有十个线程同时尝试修改MainSomeClassAList对象,其中一些线程必然会强制重新分配内部缓冲区。 照原样,如果您在末尾打印出列表的Count ,您会发现它并不总是应有的10。

为了使代码真正正确,您需要在AddToMainClassAList()方法中对Add()的调用周围添加同步。 同样的情况适用于StartThread()方法和SomeClassaAList对象。

最后,您等待线程的方法非常差。 您应尽一切努力避免轮询。 在这种情况下, Thread.Join()方法是一个合理的选择(您应该尝试完全避免阻塞线程,但是在此示例中,这是不可避免的)。 例如,您的忙循环可以替换为:

foreach (Thread thread in ThreadList)
{
    thread.Join();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM