Подтвердить что ты не робот

С# Время жизни объекта

Предположим, что у меня есть код следующим образом:

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

Есть 2 потока, я собираюсь вызывать Main thread поток, который выполняет функцию Main(), и поток, который обновляется внутри теста "if" как Thread A.

Мой вопрос в том, когда Thread A будет уничтожен? Удастся ли выполнить doSomeLenghtyOperation()?

Поскольку ссылок на Thread A нет, будет ли он помечен как кандидат на сбор мусора:

  • Сразу после завершения самой новой инструкции Thread(). Start()?
  • Сразу после завершения "if (true)" области?
  • После завершения выполнения doSomeLengthOperation()?
  • Никогда?

Все примеры, которые я вижу, являются Main(), содержащими ссылку, а затем Main thread, ожидающие соединения с потоком A перед выходом. Мне любопытно, какова продолжительность жизни кода выше.

Спасибо заранее!

4b9b3361

Ответ 1

Объект Thread будет иметь право на сбор мусора, как только он больше не будет использоваться, т.е. сразу после вызова метода Start. (Однако он не будет собран сразу, поскольку сборщик мусора работает в определенное время.)

Фактический поток, однако, не полагается на объект Thread и будет продолжать работать, даже если объект Thread будет собран.

Если поток продолжает работать, когда основной метод завершается, приложение не закончится до тех пор, пока поток не завершится, если вы не отметили поток как фоновый поток.

Ответ 2

Слово "поток" может означать здесь несколько вещей:

  • Объект System.Threading.Thread(созданный new Thread()),
  • поток CLR (управляемый поток),
  • поток ОС (не управляемый поток).

Объект Thread будет кандидатом для GC, как только метод Start() будет завершен, потому что ссылок на него больше нет.

Управляемый поток останется в живых, пока выполняется doSomeLengthyOperation().

Цитата статья Джеймса Ковача, Microsoft MVP:

Время жизни управляемого потока независимо от объекта Thread, который создает это, очень хорошая вещь, данная что вы не хотите, чтобы GC прекратить поток, который все еще делать работу просто потому, что вы потеряли все ссылки на связанный поток объект. Таким образом, GC собирает Объект Thread, но не фактический управляемый поток.

В статье также содержатся полезные примеры кода, если вы хотите поэкспериментировать.

Поток операционной системы, теоретически, не имеет отношения "один к одному" с управляемыми потоками. Из MSDN:

... сложный хост может использовать CLR Hosting API для планирования многих управляемых потоков против одного и того же потока операционной системы или для перемещения управляемого потока между различными потоками операционной системы.

Однако на практике поток CLR отображается непосредственно на поток Windows сегодня.

Ответ 3

когда Thread A будет уничтожен?

Когда doSomeLengthyOperation заканчивается.

Будет ли doSomeLenghtyOperation() работать с завершением

Да, даже если основной поток существует, потому что это не фоновый поток. Если вы устанавливаете свойство IsBackground на true перед тем, как начать поток всякий раз, когда основной поток существует, этот поток также будет остановлен.

Ответ 4

Это отличный вопрос! Тема наверняка закончится, и вы сможете попробовать это сами. Но это может стать интересным, если вы вызовете GC.Collect() в то время. Согласно Richter С# через CLR, это будет сбор мусора.

UPDATE

Я считаю, что это не будет мусор, собранный с момента Thread.CurrentThread сохраняет его в памяти, имея ссылку.