2010-05-06 11 views
37

Se ho il seguente blocco di codice in un metodo (utilizzando .NET 4 e la Biblioteca Task Parallel):Le istanze di .NET Task possono uscire dall'ambito durante l'esecuzione?

var task = new Task(() => DoSomethingLongRunning()); 
task.Start(); 

e il metodo restituisce, sarà che compito andare fuori portata ed essere garbage collection, o correrà fino al completamento? Non ho notato alcun problema con GCing, ma voglio assicurarmi che non mi stia preparando per una gara con il GC.

+0

Ho trovato una piccola cosa su questo dopo un po 'e ho pensato di condividere con voi, per completezza ... Vedi l'aggiornamento qui sotto. –

risposta

30

Aggiornamento:

Dopo aver risposto a questa domanda (! Molto tempo fa) ho scoperto che non è vero che i compiti saranno sempre correre a compimento - c'è un piccolo, diciamo caso "corner", dove le attività potrebbero non finire.

Il motivo è questo: come ho risposto in precedenza, le attività sono essenzialmente thread; ma sono background thread. I thread in background vengono automaticamente interrotti quando tutti i thread in primo piano sono terminati. Quindi, se non si esegue alcuna operazione con l'attività e il programma termina, è possibile che l'attività non venga completata.

Si dovrebbe sempre attendere le attività. Ulteriori informazioni possono essere trovate su excellent answer Jon gave me.


originale:

Task sono programmati per ThreadPool, nel senso che sono essenzialmente threads¹ (in realtà, che incapsulano fili).

Dal Thread documentation:

Non è necessario mantenere un riferimento a un oggetto Thread una volta che avete iniziato il filo. La discussione continua a essere eseguita finché la procedura thread non è stata completata.

Quindi, no, non è necessario mantenere un riferimento ad esso.

Inoltre, la documentation afferma che il modo migliore per creare un compito è quello di usarlo di fabbrica:

È inoltre possibile utilizzare il metodo StartNew per creare e avviare un'attività in uno operazione. Questo è il modo preferito per creare e avviare le attività se la creazione e la programmazione non devono essere separati (...)

Speranza che aiuta.


¹ conseguenza alla documentation:

Un'attività rappresenta un un'operazione asincrona, e per certi versi assomiglia alla creazione di un nuovo elemento di lavoro filo o ThreadPool, ma ad un più alto livello di astrazione.

11

L'attività verrà completata. Anche se non ci sono altri riferimenti ad esso (non essendo rootato credo sia il termine), il pool di thread avrà ancora un riferimento ad esso e impedirà che sia Garbage Collection almeno (dico almeno, perché anche dopo il completamento, non è garantito che sarà Garbage Collected) fino al completamento.

+0

Sì, 'rooted' è il termine corretto. Finché * qualcosa * ha un riferimento valido (attivo) all'istanza dell'attività, non sarà idoneo per la raccolta. In questo caso, il pool di thread stesso manterrà tale riferimento fino al completamento del thread. –

+5

Per essere più precisi, il programmatore di attività di TPL avrà un riferimento all'attività mentre è in esecuzione. Senza questo riferimento, l'attività potrebbe essere raccolta dati inutili, ma ciò non fermerà il codice che viene eseguito dalla finitura. – Steven