Après avoir lu Parallel.ForEach continue de générer de nouveaux threads Je doute toujours que ce soit une méthode correcte pour compter le nombre de threads simultanés?
Ce que je vois, c'est que la méthode compte le nombre d'itérations (boucles) entrées simultanément mais non terminées dans Parallel.ForEach
.
Est-ce synonyme du nombre de threads simultanés véhiculant le nombre correct de threads exécutés simultanément?
Je ne suis pas spécialiste mais je peux imaginer que:
Quoi qu'il en soit, comment compter directement la quantité de threads en cours d'exécution du processus .NET, de préférence en code (C #)?
Mise à jour:
Donc, si pour suivre le réponse de Jeppe Stig Nielsen et utiliser pour compter
directThreadsCount = Process.GetCurrentProcess().Threads.Count;
alors la sortie est, à la fois en mode Release (threadsCount == 7) et Debug (threadsCount == 15) est très similaire:
[Job 0 complete. 2 threads remaining but directThreadsCount == 7
[Job 1 complete. 1 threads remaining but directThreadsCount == 7
[Job 2 complete. 2 threads remaining but directThreadsCount == 7
[Job 4 complete. 2 threads remaining but directThreadsCount == 7
[Job 5 complete. 2 threads remaining but directThreadsCount == 7
[Job 3 complete. 2 threads remaining but directThreadsCount == 7
[Job 6 complete. 2 threads remaining but directThreadsCount == 7
[Job 9 complete. 2 threads remaining but directThreadsCount == 7
[Job 7 complete. 1 threads remaining but directThreadsCount == 7
[Job 8 complete. 0 threads remaining but directThreadsCount == 7
FINISHED
Autrement dit, le nombre de threads ne diminue jamais en disant que la méthode citée ci-dessus est incorrect tandis que System.Diagnostics.ProcessThread
donne "Class name is not valid at this point"
Mes conclusions sont-elles correctes et pourquoi ne peut-on pas utiliser ?ProcessThread
Le code utilisé de l'application console C #:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Edit4Posting
{
public class Node
{
public Node Previous { get; private set; }
public Node(Node previous)
{
Previous = previous;
}
}
public class Edit4Posting
{
public static void Main(string[] args)
{
int concurrentThreads = 0;
int directThreadsCount = 0;
int diagThreadCount = 0;
var jobs = Enumerable.Range(0, 10);
Parallel.ForEach(jobs, delegate(int jobNr)
{
int threadsRemaining = Interlocked.Increment(ref concurrentThreads);
int heavyness = jobNr % 9;
//Give the processor and the garbage collector something to do...
List<Node> nodes = new List<Node>();
Node current = null;
//for (int y = 0; y < 1024 * 1024 * heavyness; y++)
for (int y = 0; y < 1024 * 24 * heavyness; y++)
{
current = new Node(current);
nodes.Add(current);
}
//*******************************
//uncommenting next line gives: "Class name is not valid at this point"
//diagThreadCount=System.Diagnostics.ProcessThread
directThreadsCount = Process.GetCurrentProcess().Threads.Count;
//*******************************
threadsRemaining = Interlocked.Decrement(ref concurrentThreads);
Console.WriteLine(
"[Job {0} complete. {1} threads remaining but directThreadsCount == {2}",
jobNr, threadsRemaining, directThreadsCount);
});
Console.WriteLine("FINISHED");
Console.ReadLine();
}
}
}
Il existe différents types de fils, je pense. Les threads du système d'exploitation pour l'application que vous exécutez peuvent être comptés avec:
int number = Process.GetCurrentProcess().Threads.Count;
Il semble compter System.Diagnostics.ProcessThread
les instances. Vous devez peut-être compter un autre type de fil, comme les "fils gérés", donc je ne suis pas sûr que ma réponse soit ce que vous cherchez.
Je ne suis pas un spécialiste mais je peux imaginer que les threads peuvent être réutilisés pendant que son activité est échangée quelque part.
Non - à part certains cas très spécifiques (dont vous n'avez certainement pas besoin de vous inquiéter), les threads ne sont pas utilisés de manière réentrante. Le thread sera réutilisé pour exécuter une autre itération (ou une autre tâche) après l'itération actuelle est terminée, mais il ne sera pas demandé de faire autre chose pendant votre code est en cours d'exécution.
Donc, votre approche actuelle est raisonnable, essentiellement.
Quoi qu'il en soit, comment compter directement la quantité de threads en cours d'exécution dans .NET?
Vous pouvez regarder dans perfmon, qui le représentera graphiquement pour vous. (Si le processus est sous votre contrôle, il est plus simple de démarrer le processus mais faites-le attendre l'entrée, puis ouvrez perfmon, ajoutez un compteur à partir des options "Processus", sélectionnez "Thread Count" comme compteur à ajouter et limitez dans le menu déroulant qui vous intéresse. Cliquez sur OK, puis faites démarrer votre processus.)
EDIT: Pour répondre à la mise à jour:
Autrement dit, le nombre de threads ne diminue jamais indiquant que la méthode citée ci-dessus est incorrecte
Non, tout ce que cela montre, c'est que le nombre de threads exécutant activement votre code diminue, mais les threads sont conservés. C'est tout à fait naturel pour un pool de threads.
pourquoi
ProcessThread
ne peut-il pas être utilisé?
Vous l'utilisez simplement de manière inappropriée. Jeppe a dit que le système était en comptant les instances de ProcessThread
alors que votre code essaie d'assigner une classe à une variable:
diagThreadCount=System.Diagnostics.ProcessThread
C'est tout simplement un code invalide. Le message d'erreur montre que le compilateur se rend compte que c'est le nom d'un type, mais vous ne pouvez pas simplement attribuer un nom de type à une variable.