Déterminer si tous les threads ont fini c#
Je suis très nouveau à l'enfilage, en tant que débutant en C#. J'ai un programme qui sera tir plusieurs threads à l'intérieur d'une application windows. Mon objectif est de commencer un nouveau thread pour chaque élément dans une liste. Les éléments de cette liste sont des noms de station de travail sur anetwork. Chaque thread est créé va chercher à faire des réparations sur chaque machine, lorsque le thread a fini, il va écrire dans un fichier journal de toutes les erreurs trouvées etc. Mais ce que je veux être en mesure de déterminer, c'est lorsque tous les threads ont fini. Donc, si j'ai 100 machines, 100 threads, comment puis-je déterminer quand tous ont fermé?
Heres ma méthode ci-dessous :-
private void repairClientsToolStripMenuItem_Click(object sender, EventArgs e)
{
if (machineList.Count() != 0)
{
foreach (string ws in machineList)
{
new Thread(new ParameterizedThreadStart(fixClient), stack).Start(ws);
}
}
else
{
MessageBox.Show("Please import data before attempting this procedure");
}
}
Il y a une belle méthode pour les Tâches,
Task.WaitAll
(msdn.microsoft.com/en-us/library/dd270695.aspx). Bien sûr, si vous devez utiliser des threads, ce qui n'aidera pas.Je recommande également que vous commencez à utiliser la Task Parallel library.
pas un doublon. Le lien n'indique pas ou de la mention d'un GUI de gestionnaire d'événements. Toute solution qui implique d'attendre sur un sunchro objet comme Join() ou WFMO(), ne doit pas être utilisé à l'intérieur d'un gestionnaire d'événements. La terminé l'exécution de la dernière tâche doit déclencher l'Invoquer/BeginInvoke l'exécution d'un délégué sur le thread GUI.
Ok answerers comment 'bout nous nous arrêtons suggérant blocage des appels sur le thread d'INTERFACE utilisateur hein?
OriginalL'auteur Derek | 2012-04-24
Vous devez vous connecter pour publier un commentaire.
La façon de le faire serait de garder une référence pour tous les threads et puis Rejoindre sur eux. Cela signifie essentiellement que le thread en cours bloquera jusqu'à ce que le joint thread se termine.
Changer votre boucle à quelque chose comme:
(où _machineThreads est une liste de
System.Thread
)Vous pouvez bloquer jusqu'à ce que tous sont complets avec quelque chose comme:
CEPENDANT - vous avez presque certainement ne voulez pas faire cela pour le scénario que vous décrivez:
Il y a une différence ive limitée chaque thread à 32 ko? J'étais un peu inquiet de l'utilisation de la mémoire que j'avais créer sur le serveur, mais bien que de la limiter à 32 ko serait suffisant?
Ce n'est pas seulement l'utilisation de la mémoire - création d'un thread est cher, par rapport à l'utilisation du pool de threads. Aussi, je ne sais pas ce que vos fils sont en train de faire, mais si elles ne sont bouteille à col ailleurs - peut-être par les e / s de disque ou accès de base de données, puis ils vont tous être en train d'essayer de courir en permanence. Cela signifie que le PROCESSEUR aurez à passer beaucoup de temps juste de commutation entre les threads plutôt que de les exécuter. La commutation de threads est également coûteux. Il est souvent plus rapide d'avoir un plus petit nombre de threads et de les réutiliser, que de créer des charges de fils et de les avoir en concurrence pour le temps PROCESSEUR.
a parfaitement fonctionné avec moi. Merci 🙂
OriginalL'auteur Rob Levine
vous pouvez utiliser: IsAlive. Mais vous devez garder une référence comme
OriginalL'auteur jorne
Une autre idée serait d'utiliser en Parallèle.ForEach dans un autre thread:
C'est également sans danger si vous avez trop beaucoup de machines, pour résoudre
Au moins, il n'est pas bloquer le thread d'INTERFACE utilisateur comme beaucoup d'autres réponses 🙂
OriginalL'auteur weismat
Ne jamais attendre pour le fil d'achèvement, ou quoi que ce soit d'autre, dans une interface graphique un gestionnaire d'événement. Si vous frayer plusieurs threads, (et oui, ne pas le faire - voir le post de Rob), ou présenter de nombreuses tâches à un pool de threads, le dernier entitiy à l'exécution complète des signaux le thread GUI que le travail est terminé. Habituellement, cela implique de remettre en certains objets qui compte le reste des tâches/threads et des signaux lorsque le dernier des feux. Regarder Système.Le filetage.CountdownEvent.
Thread.Join
,WaitHandle.WaitOne
, etc. ne fonctionne pas sur le thread d'INTERFACE utilisateur.OriginalL'auteur Martin James
Il est une autre façon de faire qui utilise le CountdownEvent classe.
Le code qui commence le fils doit incrémenter un compteur, et passer un CountdownEvent objet à chaque thread. Chaque thread va appeler CountdownEvent.Signal() quand c'est fini.
Le code suivant illustre cette approche:
Non,
CountdownEvent.Wait
ne pompe pas les messages de sorte qu'il serait trop bloquer le thread d'INTERFACE utilisateur.Oui, la bonne chose à faire serait d'avoir un autre thread qui appelle finishedSignal.Wait (), puis utilise BeginInvoke() pour appeler une méthode appropriée sur le thread de l'INTERFACE utilisateur.
OriginalL'auteur Matthew Watson
De Brian solution n'est pas complète et génère une erreur de syntaxe. Si ce n'est pour l'erreur de syntaxe, il serait de travailler et de résoudre la première affiche du problème. Je ne sais pas comment réparer l'erreur de syntaxe donc je poste cette question, pour être résolu, de sorte que la question initiale peut être résolu. S'il vous plaît Ne Pas supprimer ce message. il est pertinent à la question initiale posée.
@Brian Gédéon: Votre solution, ce serait parfait, à l'exception du code suivant:
Le problème avec cela est dans l' () => partie. Ceci est la production d'une erreur de syntaxe qui se lit Système de Délégué.L'Action "Du Système.Le filetage.Les tâches.Tâche" ne prend pas de 0 arguments
Je souhaite vraiment que ce serait le travail et je ne connais pas la solution à cette question. J'ai essayé de chercher l'erreur, mais je ne suis pas la compréhension de ce que les paramètres de son exigeant. Si quelqu'un peut répondre à cela, il serait extrêmement utile. C'est la seule pièce manquante à ce problème.
OriginalL'auteur Excuseme baking powder
Laissez-nous obtenir quelque chose hors de la voie d'abord.
Thread.Join
,WaitHandle.WaitOne
, ou de tout autre mécanisme de blocage.Ici est de savoir comment je le faire avec le TPL.
Ce que je fais ici est la création d'un parent tâche qui va lui-même faire tourner des tâches enfants. Notez que j'utilise
TaskCreationOptions.AttachedToParent
associer à l'enfant des tâches avec leur parent. Puis sur la tâche parente j'appelleContinueWith
qui est exécuté après la mère et de tous ses enfants ont terminé. J'utiliseTaskScheduler.FromCurrentSynchronizationContext
pour obtenir la poursuite d'arriver sur le thread d'INTERFACE utilisateur.Et voici une autre solution à l'aide de
Parallel.ForEach
. Remarquez que c'est un peu la solution de nettoyage.Merci pour ce la raison pour laquelle mon attention. Je crois que je l'ai corrigé.
OriginalL'auteur Brian Gideon
Vous pouvez créer
WaitHandle
pour chaque thread, vous êtes en attente pour:Ajouter
ManualResetEvent
à la liste et de les passer au fil de discussion:L'intérieur de vous-méthode de fil:
Thread principal continuera d'exécution lorsque tous les threads de définir le temps d'attente des poignées.
WaitHandle.WaitAll
n'est pas une mauvaise option, dans certains cas, mais dans ce cas, il va bloquer le thread d'INTERFACE utilisateur. Eh bien, en fait pour être complètement padantic il va lever une exception, car il a une 64 poignée de limite.merci, tu ne connaissais pas les poignées de limite de nombre de!
OriginalL'auteur Sergey Berezovskiy