假设我的代码如下:

int Main()
{
    if (true)
    {
       new Thread(()=>
          {
              doSomeLengthyOperation();
          }).Start();
    }
    while (true)
    {
       //do nothing
    }
}

有2个线程,我将调用主线程为执行main()函数的线程,并且该线程在“ If”测试中为线程A中为A。

我的问题是,线程何时被摧毁? Dosomelenghtyoperation()能够完成吗?

由于没有指向线程A的参考文献,是否会标记为垃圾收集的候选者:

  1. 在“ new thread()。start()”语句本身完成后立即完成?
  2. “如果(true)”范围退出后立即?
  3. DosomeLengtheroperation()运行到完成后?
  4. 绝不?

我看到的所有示例都是主()保存参考,然后在退出之前等待与线程A连接的主线程。我很好奇上述代码的寿命是什么。

提前致谢!

有帮助吗?

解决方案

Thread 一旦不再使用,对象将有资格获得垃圾收集,即致电后立即使用 Start 方法。 (但是,随着垃圾收集器在特定的时间运行,它不会立即收集。)

但是,实际线程并不依赖于 Thread 对象,即使 Thread 收集对象。

如果当主方法退出时该线程仍在运行,则除非您将线程标记为背景线程,否则该应用程序将在线程完成之前不会结束。

其他提示

单词“线程”在这里可能意味着几件事:

  • system.threading.thread对象(由 new Thread()),
  • CLR线程(托管线程),
  • OS线程(未管理的线程)。

启动()方法完成后,线程对象将立即成为GC的候选,因为不再参考它。

托管线程将在DosomeLengthYoperation()运行时都活着。

引用 文章 由Microsoft MVP詹姆斯·科瓦克斯(James Kovacs):

托管线程的寿命独立于创建它的线程对象,这是一件非常好的事情,因为您不希望GC终止仍在进行工作的线程,仅仅是因为您丢失了对关联线程对象的所有引用。因此,GC正在收集线程对象,而不是实际的托管线程。

如果您想尝试一下,本文还包含一些有用的代码示例。

从理论上讲,操作系统线程与托管线程没有一对一的关系。从 MSDN:

...复杂的主机可以使用CLR托管API来安排许多托管线程针对相同的操作系统线程,或者在不同的操作系统线程之间移动托管线程。

但是,实际上,CLR线程 今天直接映射到Windows线程.

线程什么时候被摧毁?

什么时候 doSomeLengthyOperation 完成。

dosomelenghtyoperation()能够完成

是的,即使主线程存在,因为它不是背景线程。如果您设置 isbackground 财产为 true 每当主线存在时启动线程之前,此线程也将停止。

这是一个很好的问题!线程肯定会完成,您可以自己尝试。但是,如果您在一段时间内调用gc.collect(),它可能会变得有趣。根据Richter的C#通过CLR的说法,将收集垃圾。

更新

我相信它不会是垃圾收集的,因为线程通过参考将其保存在内存中。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top