Vida útil do object de encadeamento C #

Suponha que eu tenha um código como segue:

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

Existem 2 threads, eu vou chamar o thread principal o segmento que está executando a function Main () e o thread sendo new’ed up dentro do “if” testar como thread A.

Minha pergunta é: quando o Thread A é destruído? Será que o SomeLenghtyOperation () será capaz de executar a conclusão?

Como não há referências apontando para o Thread A, ele será marcado como candidato à garbage collection:

  1. Imediatamente após o “novo Thread (). Start ()” declaração em si termina?
  2. Imediatamente após o escopo “if (true)” é encerrado?
  3. Depois que o doSomeLengthOperation () é executado para terminar?
  4. Nunca?

Todos os exemplos que vejo são o Main () mantendo a referência, e então o Main thread esperando para unir-se ao thread A antes de sair. Estou curioso para saber qual é a duração do código acima.

Desde já, obrigado!

O object Thread estará qualificado para a garbage collection assim que não for mais usado, ou seja, imediatamente após chamar o método Start . (No entanto, ele não será coletado imediatamente, pois o coletor de lixo é executado em horários específicos.)

No entanto, o segmento real não está contando com o object Thread e continuará a ser executado mesmo se o object Thread for coletado.

Se o segmento ainda estiver sendo executado quando o método principal for encerrado, o aplicativo não terminará até que o segmento seja concluído, a menos que você tenha marcado o segmento como um segmento de plano de fundo.

Palavra “thread” pode significar várias coisas aqui:

  • Objeto System.Threading.Thread (criado pelo new Thread() ),
  • Encadeamento CLR (encadeamento gerenciado),
  • Thread do SO (thread não gerenciado).

O object Thread será candidato a GC assim que o método Start () for concluído, porque não há mais referências a ele.

O thread gerenciado permanecerá ativo enquanto doSomeLengthyOperation () é executado.

Citando o artigo de James Kovacs, MVP da Microsoft:

O tempo de vida de um thread gerenciado é independente do object Thread que o cria, uma coisa muito boa, pois você não desejaria que o GC terminasse um thread que ainda estava trabalhando simplesmente porque você perdeu todas as referências ao object Thread associado. Portanto, o GC está coletando o object Thread, mas não o encadeamento gerenciado real.

O artigo também contém alguns exemplos de códigos úteis se você quiser experimentar.

O encadeamento do sistema operacional, teoricamente, não possui relacionamento de um para um com encadeamentos gerenciados. Do MSDN :

… um host sofisticado pode usar a CLR Hosting API para agendar muitos encadeamentos gerenciados no mesmo encadeamento do sistema operacional ou para mover um encadeamento gerenciado entre diferentes encadeamentos do sistema operacional.

Na prática, no entanto, o encadeamento CLR mapeia diretamente para um encadeamento do Windows hoje .

quando o Thread A é destruído?

Quando doSomeLengthyOperation concluído.

Será que doSomeLenghtyOperation () será capaz de executar a conclusão

Sim, mesmo se o thread principal existir porque não é um thread de segundo plano. Se você definir a propriedade IsBackground como true antes de iniciar o thread sempre que o thread principal existir, esse thread também será interrompido.

Esta é uma excelente pergunta! Thread certamente vai terminar e você pode tentar isso sozinho. Mas pode ficar interessante se você chamar GC.Collect () no tempo. De acordo com o C # de Richter via CLR, será coletado lixo.

ATUALIZAR

Eu acredito que não será Garbage Collected desde Thread.CurrentThread mantém na memory, tendo uma referência.