Il thread non verrà raccolto, poiché ogni thread in esecuzione, in attesa o sospeso viene utilizzato dal GC stesso per decidere cosa è attivo (tracciare tutto nello stack di ogni thread, tracciare tutto ciò che fa riferimento a tutti quegli oggetti, quindi tutto referenziati da quelli, e così via, e hai identificato tutto ciò che non può essere raccolto dalla spazzatura).
Il thread potrebbe terminare, se si trattasse di un thread in background, perché verrà arrestato attivamente quando tutti gli altri thread nel processo saranno terminati. In caso contrario, l'unica cosa che causerà la morte è il processo in corso di uscita, un'eccezione (incluso ThreadAbortException
) o l'interruzione del ciclo while
stesso.
C'è un caso che è paragonabile per certi versi, che può essere quello che state pensando di:
var timer = new System.Threading.Timer(someCallback, null, new TimeSpan(0, 0, 5), new TimeSpan(0, 0, 5));
int someResult = doingSomethingElse();
doSomethingElseThatTakesLongerThan5Seconds();
Questo è un altro pezzo di codice che causa un altro thread di esecuzione per fare qualcosa. In questo caso, il timer può effettivamente essere garbage collection prima dell'esecuzione, durante una delle esecuzioni, o praticamente in qualsiasi momento dopo il ritorno del costruttore.
La cosa importante è che non c'è un singolo thread per il timer e il thread non "sa" nemmeno dell'oggetto timer. Poiché l'ultimo accesso all'oggetto è accaduto da allora, è idoneo per la raccolta. Questo è diverso dall'argomento di un singolo thread in esecuzione (o in attesa, ecc.).
fonte
2012-01-25 23:34:10
_running thread contano come radici? _ O _referenze (all'interno di thread) che fanno riferimento a oggetti contati come radici .._? –
@Royi root - in pratica, la pila dei locali. Nota che arg0 (ovvero questo) di solito mantiene attiva anche l'istanza di destinazione –
Quindi è sbagliato/ok dire: _GC non è autorizzato a raccogliere un thread in esecuzione_? –