2010-10-04 15 views
5

Ho un'applicazione console C# che ha alcuni thread per fare un po 'di lavoro (scarica un file). ogni thread può uscire dall'applicazione in qualsiasi momento in qualsiasi punto dell'applicazione, ma mostrerò un messaggio appropriato sulla console. È possibile rintracciarli ma non ha senso per me. Voglio semplicemente controllare il conteggio dei thread o qualcosa del genere per scoprire qual è l'ultimo thread e fare qualcosa quando sta uscendo. Qual è la migliore pratica per farlo?Ultimo thread di un'applicazione multithread

pseudo codice:

if (lastThread) 
{ 
    cleanUp(); 
    Console.ReadLine(); 
} 

Grazie

+1

Quale versione di C#/.NET stai usando? –

+0

Posso usare qualsiasi versione – Xaqron

risposta

11

Questo è un luogo in cui utilizzando il Parallel Library nuova Task può rendere la vita molto più facile. Invece di creare discussioni, e girare il lavoro sul filo, è possibile utilizzare più compiti:

var task1 = Task.Factory.StartNew(() => DoTaskOneWork()); 
var task2 = Task.Factory.StartNew(() => DoTaskTwoWork()); 
var task3 = Task.Factory.StartNew(() => DoTaskThreeWork()); 

// Block until all tasks are done 

Task.WaitAll(new[] {task1, task2, task3}); 
cleanUp(); // Do your cleanup 

Se i "compiti" sono solo il download di un gruppo di singoli file, si potrebbe anche fare questo semplice utilizzando PLINQ:

var fileUrls = GetListOfUrlsToDownload(); 

fileUrls.AsParallel().ForAll(fileUrl => DownloadAndProcessFile(fileUrl)); 

cleanUp(); // Do your cleanup 
+0

+1 presumendo che stiano usando .NET 4.0. –

+0

+1 per semplificare la soluzione fire-and-forget –

+1

@Mark: non sto assumendo che lo siano - ma se non lo sono, voglio fornire la motivazione per muoverti;) –

1

tuo thread principale dovrebbe join con tutti i thread di lavoro e blocchi mentre sono in esecuzione. Quindi, quando tutti i thread sono completi, esegue il codice di pulizia e quindi si chiude.

In alternativa è possibile utilizzare uno WaitHandle come ad esempio ManualResetEvent per thread e wait for all di essi da segnalare.

+0

Ci sono molti posti diversi in cui i thread lasciano il codice. È difficile farli tornare dove e unirli a loro – Xaqron

2

Un design in cui si perde traccia delle proprie discussioni non è l'ideale.

A seconda di come vengono generati, dovrebbe essere possibile tracciare lo stato di ciascuno associando un oggetto segnalabile per thread, quindi WaitAll su quegli oggetti segnalabili.

Ogni oggetto segnalabile a sua volta deve essere segnalato all'uscita del filo. Quando vengono tutti segnalati, sai che i fili sono tutti morti e tu chiudi pulito. È necessario assicurarsi che le condizioni anomale nei thread non determinino la disattivazione dell'oggetto segnalabile associato a quel thread o che il proprio WaitAll non venga mai restituito. Ciò significa che in genere le eccezioni potrebbero utilizzare try...finally per garantire che gli oggetti vengano segnalati.

Il nuovo pseudocodice è

foreach (workitem in list of work) 
    start up thread associated with a ManualResetEvent or similar 

WaitAll for all events to be signalled 
cleanup