Comment utiliser le multi-threading dans une boucle For
Je veux atteindre le dessous de l'exigence; s'il vous plaît suggérer une solution.
string[] filenames = Directory.GetFiles("C:\Temp"); //10 files
for (int i = 0; i < filenames.count; i++)
{
ProcessFile(filenames[i]); //it takes time to execute
}
J'ai voulu mettre en place le multi-threading. e.g Il y a 10 fichiers. Je voulais processus 3 fichiers à la fois (configurable, dire maxthreadcount
). Donc 3 fichiers seront traités dans les 3 fils de la boucle for et si un thread termine l'exécution, il doit choisir le prochain élément de la boucle for. Voulait aussi s'assurer que tous les fichiers sont traités avant de sortir de la boucle for.
S'il vous plaît suggérer la meilleure approche.
Vous êtes vraiment coincé sur .NET 2.0? Il va être beaucoup mieux approches .NET 3.5, ou mieux encore 4.0.
Toute suggestion à l'aide de pool de threads ou de Sémaphore?
Non, à l'exception: de l'OUBLIER, à moins que votre traitement est intensif pour le CPU. Le Disque n'obtient pas comme par magie plus rapide. IO va être un sérieux goulot d'étranglement contenter.
Parce que si c'est BEAUCOUP, l'OI SERA le goulot d'étranglement. Sérieusement. Vous avez une idée de comment RALENTIR un disque est en fait par rapport à un PROCESSEUR core? Il va prendre BEAUCOUP de traitement à l'équilibre.
Le goulot d'étranglement peut ne pas se produire si le fichier ne prend pas beaucoup de temps pour lire. Peut-être que le "il faut du temps pour exécuter" est attaché à traiter les données à partir du fichier une fois qu'il est chargé, dans ce cas c'est une bonne idée d'aller faire un multi-thread pour cela. Si le retard est parce que le fichier prend beaucoup de temps pour lire, alors je suggère d'oublier le multithreading. Pour un exemple du temps perdu, copie d'un fichier énorme entre les 2 disques Durs et de regarder l'ETA - copie puis une deuxième fichier sur le dessus de cela et de voir comment l'ETA a plus que doublé! Vous voulez vraiment lire à seulement 1 fichier à la fois 😉
Toute suggestion à l'aide de pool de threads ou de Sémaphore?
Non, à l'exception: de l'OUBLIER, à moins que votre traitement est intensif pour le CPU. Le Disque n'obtient pas comme par magie plus rapide. IO va être un sérieux goulot d'étranglement contenter.
Parce que si c'est BEAUCOUP, l'OI SERA le goulot d'étranglement. Sérieusement. Vous avez une idée de comment RALENTIR un disque est en fait par rapport à un PROCESSEUR core? Il va prendre BEAUCOUP de traitement à l'équilibre.
Le goulot d'étranglement peut ne pas se produire si le fichier ne prend pas beaucoup de temps pour lire. Peut-être que le "il faut du temps pour exécuter" est attaché à traiter les données à partir du fichier une fois qu'il est chargé, dans ce cas c'est une bonne idée d'aller faire un multi-thread pour cela. Si le retard est parce que le fichier prend beaucoup de temps pour lire, alors je suggère d'oublier le multithreading. Pour un exemple du temps perdu, copie d'un fichier énorme entre les 2 disques Durs et de regarder l'ETA - copie puis une deuxième fichier sur le dessus de cela et de voir comment l'ETA a plus que doublé! Vous voulez vraiment lire à seulement 1 fichier à la fois 😉
OriginalL'auteur SAM | 2012-12-23
Vous devez vous connecter pour publier un commentaire.
Ce sera de faire le travail .net 2.0:
workingCounter
exception, il va causer des problèmes.Il y a un problème avec la décrémentation de workingCounter - qui n'est pas une opération atomique. Deux threads peut décrémenter à la même heure et le compteur ne sera décrémenté à la fois. Il est préférable d'utiliser Interloqué.Décrémenter(réf workingCounter).
J'ai intégré les deux suggestions par @CodingWithSpike et ytoledano pour faire de cet échantillon plus robuste
comment s'assurer que tous les threads ont terminé leur exécution avant que la Boucle se termine à l'aide de code ci-dessus? J'ai essayé le code ci-dessus, mais pour la boucle s'arrête, avant de threads complète de leur exécution.
Avez-vous incorporé essayez->attraper à l'intérieur de votre code comme dans les mises à jour de l'échantillon? Lors de l'appel de feuilles ProcessFile (en fin de compte à l'intérieur de bloc finally) puis thread est sur le point de terminer. Si une exception a été levée vous devez manipuler à l'intérieur du bloc catch.
OriginalL'auteur Gregor Primar
Essayer
MSDN
Il est uniquement disponible depuis .Net 4. Espérons qu'acceptable.
OriginalL'auteur ytoledano
Prendre un coup d'oeil à la Producteur/Consommateur exemple de la File d'attente par Joe Albahari. Il devrait fournir un bon point de départ pour ce que vous essayez d'accomplir.
OriginalL'auteur RePierre
Vous pouvez utiliser le ThreadPool.
Exemple:
Si vous utilisez le pool de threads ailleurs, dans votre application, puis ce ne serait pas une bonne solution, car il est partagé entre votre application.
Vous pouvez également saisir un autre pool de threads mise en œuvre, par exemple SmartThreadPool
OriginalL'auteur CodingWithSpike
Plutôt que de partir un thread pour chaque nom de fichier, mettre les noms de fichiers dans une file d'attente, puis démarrez à trois fils pour les traiter. Ou, depuis le thread principal est maintenant libre, lance deux threads et de laisser le thread principal travail sur elle, trop:
Une autre option est d'utiliser un sémaphore pour contrôler le nombre de threads de travail:
La première va effectuer un peu mieux parce que vous n'avez pas la surcharge de démarrage et d'arrêt d'un thread pour chaque nom de fichier de traitement. La deuxième est beaucoup plus court et plus, cependant, et tire pleinement parti du pool de threads. Il est probable que vous ne remarquerez pas la différence de performances.
OriginalL'auteur Jim Mischel
Pouvez définir max de threads unsing ParallelOptions
En parallèle.Pour La Méthode (Int32 Int32, ParallelOptions, Action)
ParallelOptions.MaxDegreeOfParallelism
OriginalL'auteur paparazzo
OriginalL'auteur David Vu