5 votes

Dernier thread d'une application multithread

J'ai une application console en c# qui a plusieurs threads pour faire un travail (télécharger un fichier). Chaque thread peut quitter l'application à tout moment, n'importe où dans l'application, mais j'afficherai un message approprié sur la console. Il est possible de les suivre mais cela n'a pas de 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 se termine. Quelle est la meilleure pratique pour le faire ?

pseudo-code :

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

Remerciements

11voto

Reed Copsey Points 315315

C'est un domaine où l'utilisation de la nouvelle bibliothèque de tâches parallèles peut rendre la vie beaucoup plus facile. Au lieu de créer des fils de discussion et de faire tourner le travail sur le fil de discussion, 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" consistent simplement à télécharger un ensemble de fichiers individuels, vous pouvez même simplifier les choses en utilisant PLINQ :

var fileUrls = GetListOfUrlsToDownload();

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

cleanUp(); // Do your cleanup

2voto

Steve Townsend Points 36948

Une conception où l'on perd la trace de ses fils n'est pas idéale.

Selon la façon dont vous les créez, il devrait être possible de suivre l'état de chacun en associant un objet signalable par thread, puis AttendreTout sur ces objets signalables.

Chaque objet signalable doit à son tour être signalé lorsque son fil d'exécution se termine. Lorsqu'ils sont tous signalés, vous savez que les threads sont tous morts et vous fermez proprement. Vous devez vous assurer que des conditions anormales dans vos threads n'ont pas pour conséquence que l'objet signalable associé à ce thread reste non défini, ou que votre WaitAll ne reviendra jamais. Cela signifie que les exceptions - typiquement - pourraient utiliser try...finally pour s'assurer que les objets sont signalés.

Votre nouveau pseudocode est le suivant

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

WaitAll for all events to be signalled
cleanup

1voto

Mark Byers Points 318575

Votre fil conducteur doit rejoindre avec tous vos threads de travail et 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 et quitte.

Vous pouvez également utiliser un Poignée d'attente comme par exemple ManualResetEvent (événement de réinitialisation manuelle) par fil et attendre tous d'entre eux à signaler.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X