简体   繁体   English

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

[英]How to start a thread within another thread

I am exploring with the concept of starting a thread within another thread. 我正在探索在另一个线程中启动一个线程的概念。 this is the code I have come up with, this is watered down version of another program which I am developing currently however I found out that the second level of threads do not complete successfully. 这是我想出的代码,这是我当前正在开发的另一个程序的精简版本,但是我发现第二级线程无法成功完成。

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

    }
}

The above code does not print out "hello" and exits without creating the SomeClassA List. 上面的代码不会打印出“ hello”,并在不创建SomeClassA列表的情况下退出。

The problem with your code is that you never start the inner threads. 代码的问题在于,您永远不会启动内部线程。 Change you constructor to look like this, and it will work: 更改您的构造函数,使其看起来像这样,它将起作用:

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

That said, I should point out that you're lucky the program doesn't crash. 就是说,我应该指出,您很幸运该程序没有崩溃。 You have ten threads concurrently trying to modify the MainSomeClassAList object, some of which will necessarily force a reallocation of the internal buffer. 您有十个线程同时尝试修改MainSomeClassAList对象,其中一些线程必然会强制重新分配内部缓冲区。 As it is, if you print out the Count of the list at the end, you will find it isn't always 10 as it ought to be. 照原样,如果您在末尾打印出列表的Count ,您会发现它并不总是应有的10。

For the code to be truly correct, you would need to add synchronization around the call to Add() in the AddToMainClassAList() method. 为了使代码真正正确,您需要在AddToMainClassAList()方法中对Add()的调用周围添加同步。 Same thing applies to the StartThread() method and the SomeClassaAList object. 同样的情况适用于StartThread()方法和SomeClassaAList对象。

Finally, your method for waiting on the threads is very poor. 最后,您等待线程的方法非常差。 You should try to avoid polling at all costs. 您应尽一切努力避免轮询。 In this case, the Thread.Join() method is a reasonable choice (you should try to avoid blocking a thread at all, but for this example, it's unavoidable). 在这种情况下, Thread.Join()方法是一个合理的选择(您应该尝试完全避免阻塞线程,但是在此示例中,这是不可避免的)。 For example, your busy loop can be replaced by this: 例如,您的忙循环可以替换为:

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

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

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