2010-10-04 5 views
5

J'ai une application de console C# qui a quelques threads pour faire un peu de travail (télécharger un fichier). chaque thread peut quitter l'application à tout moment n'importe où dans l'application, mais je vais montrer un message approprié sur la console. Il est possible de les suivre mais cela n'a aucun sens pour moi. Je veux simplement vérifier le nombre de threads ou quelque chose comme ça pour savoir lequel est le dernier thread et faire quelque chose quand il sort. Quelle est la meilleure pratique pour le faire?Dernier thread d'une application multithread

code pseudo:

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

Merci

+1

Quelle version de C#/.NET utilisez-vous? –

+0

Je peux utiliser n'importe quelle version – Xaqron

Répondre

11

C'est un endroit où l'utilisation de la nouvelle bibliothèque parallèle de tâches peut rendre la vie beaucoup plus facile. Au lieu de créer des fils, et tourner le travail sur le fil, vous pouvez utiliser plusieurs tâches:

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 

Si les « tâches » ne sont que le téléchargement d'un tas de fichiers individuels, vous pouvez même en faire plus simple en utilisant PLINQ:

var fileUrls = GetListOfUrlsToDownload(); 

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

cleanUp(); // Do your cleanup 
+0

+1 en supposant qu'ils utilisent .NET 4.0. –

+0

+1 pour une solution plus simple fire-and-forget –

+1

@Mark: Je ne suppose pas qu'ils sont - mais s'ils ne sont pas, je veux fournir la motivation pour se déplacer;) –

1

Votre thread principal doit join avec tous vos threads de travail et de bloquer pendant qu'ils sont en cours d'exécution. Ensuite, lorsque tous les threads sont terminés, il exécute le code de nettoyage, puis se ferme.

Vous pouvez également utiliser un WaitHandle comme ManualResetEvent par thread et wait for all pour être signalé.

+0

Il existe de nombreux endroits où les threads quittent le code. Il est difficile de les faire revenir et de les rejoindre – Xaqron

2

Un design où vous perdez la trace de vos threads n'est pas idéal. En fonction de la façon dont vous les générer, il devrait être possible de suivre l'état de chacun en associant un objet signalable par thread, puis WaitAll sur ces objets signalables.

Chaque objet pouvant être signalé doit être signalé à son tour lorsque son fil sort. Quand ils sont tous signalés, vous savez que les fils sont tous morts et vous fermez net. Vous devez vous assurer que les conditions anormales de vos threads n'entraînent pas la désactivation de l'objet signalable associé à ce thread, sinon votre WaitAll ne reviendra jamais. Cela signifie généralement des exceptions - vous pouvez utiliser try...finally pour vous assurer que les objets sont signalés.

Votre nouvelle est pseudocode

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

WaitAll for all events to be signalled 
cleanup 
Questions connexes