在这种情况下,主线程会发生什么

GET*_*Tah 3 .net c# multithreading

我有以下多线程程序:

class Program{
  static void main(){
    (new Thread(DoSomething)).Start();
  }
  static void DoSomething(){
    // Dome something here...
  }
}
Run Code Online (Sandbox Code Playgroud)

几个问题:

  1. 旋转子线程后主线程是否退出?
  2. 如果它确实退出并且子线程是后台线程:主进程是退出还是等待后台线程完成?

Moo*_*ght 7

"默认情况下,您显式创建的线程是前台线程.前景线程使应用程序保持活动状态,只要其中任何一个正在运行,而后台线程不会.一旦所有前台线程完成,应用程序结束,任何后台线程仍然突然终止.

class PriorityTest
{
    static void Main (string[] args)
    {
        Thread worker = new Thread ( () => Console.ReadLine() );
        if (args.Length > 0) worker.IsBackground = true;
        worker.Start();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果在没有任何参数的情况下调用此程序,则工作线程将采用前台状态并等待ReadLine语句,以便用户按Enter键.同时,主线程退出,但应用程序继续运行,因为前台线程仍然存在.

但是,如果将参数传递给Main(),则会为worker分配后台状态,并且当主线程结束时(终止ReadLine和程序),程序几乎立即退出.

有关更多信息,请参阅有关线程的Joseph Albahri(天才和伟人)页面(这是从中提取的).


DRo*_*son 6

通常,如果要等待子线程完成,x.Join();则需要在主线程停止的位置添加一行(其中x是线程的变量)并等待子进程完成.

编辑:是的,主要线程将退出,除非出现以下三种情况之一:a)生成的线程在主线程代码的其余部分之前完成(如果你添加任何)

b)你有一个等待线程完成的条件(比如我提到的Join语句,但还有其他方法).

c)主线程进入半无限循环(例如游戏/图形引擎).

在您的简单示例中,它将确定退出(给出您的问题的参数,后台线程).

编辑2:对不起,我似乎已经回避了你的第二个问题(实际上只考虑了背景线程).如果它是一个后台线程,它将按照我的解释退出,如果它是前景,那么它不应该(虽然我对前景线程没有太多经验,所以我不能肯定地说).

所以回答你的问题:是的,主线程退出.是的,如果孩子特别是后台线程,那么该过程也会退出.

编辑3:最后编辑,我保证.我只想添加一些代码,以便您可以自己证明答案(这总是很好):

static void Main(string[] args)
{
    Thread thready = new Thread(DoSomething);
    thready.IsBackground = true;
    thready.Start();
}

static void DoSomething()
{
    while (true)
    {
        Console.Write("thread's looping \n");
    }
}
Run Code Online (Sandbox Code Playgroud)

通过切换thready.IsBackground = true;thready.IsBackground = false;你得到一个永远运行的程序(直到该线程没有退出).保持真实状态将很快退出.


Bra*_*vic 6

取决于Thread.IsBackground.

在所有前台线程完成之前,该进程不会退出.在以下示例中......

class Program {

    static void Main(string[] args) {
        (new Thread(DoSomething)).Start();
    }

    static void DoSomething() {
        Thread.Sleep(5000);
    }

}
Run Code Online (Sandbox Code Playgroud)

...过程将在5秒后退出.

但在这个例子中......

class Program {

    static void Main(string[] args) {
        (new Thread(DoSomething) { IsBackground = true }).Start();
    }

    static void DoSomething() {
        Thread.Sleep(5000);
    }

}
Run Code Online (Sandbox Code Playgroud)

......过程将立即退出(几乎).对仍在运行的子后台线程的影响类似于强制终止进程,因此如果可能,请避免这样做.