Quel est le nombre maximal de threads que vous pouvez créer dans une application C #? Et que se passe-t-il lorsque vous atteignez cette limite? Une exception est-elle lancée?
Quel est le nombre maximal de threads que vous pouvez créer dans une application C #? Et que se passe-t-il lorsque vous atteignez cette limite? Une exception est-elle lancée?
Réponses:
Il n'y a pas de limite inhérente. Le nombre maximum de threads est déterminé par la quantité de ressources physiques disponibles. Voir cet article de Raymond Chen pour plus de détails.
Si vous avez besoin de demander quel est le nombre maximum de threads, vous faites probablement quelque chose de mal.
[ Mise à jour : Juste par intérêt: nombre de threads par défaut du pool de threads .NET:
(Ces chiffres peuvent varier en fonction du matériel et du système d'exploitation)]
Mitch a raison. Cela dépend des ressources (mémoire).
Bien que l'article de Raymond soit dédié aux threads Windows, pas aux threads C #, la logique s'applique de la même manière (les threads C # sont mappés aux threads Windows).
Cependant, comme nous sommes en C #, si nous voulons être complètement précis, nous devons faire la distinction entre les threads "démarrés" et "non démarrés". Seuls les threads démarrés réservent réellement de l'espace dans la pile (comme on pouvait s'y attendre). Les threads non démarrés n'allouent que les informations requises par un objet thread (vous pouvez utiliser le réflecteur si vous êtes intéressé par les membres réels).
Vous pouvez réellement le tester par vous-même, comparer:
static void DummyCall()
{
Thread.Sleep(1000000000);
}
static void Main(string[] args)
{
int count = 0;
var threadList = new List<Thread>();
try
{
while (true)
{
Thread newThread = new Thread(new ThreadStart(DummyCall), 1024);
newThread.Start();
threadList.Add(newThread);
count++;
}
}
catch (Exception ex)
{
}
}
avec:
static void DummyCall()
{
Thread.Sleep(1000000000);
}
static void Main(string[] args)
{
int count = 0;
var threadList = new List<Thread>();
try
{
while (true)
{
Thread newThread = new Thread(new ThreadStart(DummyCall), 1024);
threadList.Add(newThread);
count++;
}
}
catch (Exception ex)
{
}
}
Mettez un point d'arrêt dans l'exception (mémoire insuffisante, bien sûr) dans VS pour voir la valeur de counter. Il y a bien sûr une différence très significative.
Vous devez utiliser le pool de threads (ou les delgates asynchrones, qui à leur tour utilisent le pool de threads) afin que le système puisse décider du nombre de threads à exécuter.
Jeff Richter dans CLR via C #:
"Avec la version 2.0 du CLR, le nombre maximum de threads de travail par défaut est de 25 par CPU dans la machine et le nombre maximum de threads d'E / S est par défaut de 1000. Une limite de 1000 n'est en fait aucune limite."
Notez que cela est basé sur .NET 2.0. Cela peut avoir changé dans .NET 3.5.
[Edit] Comme l'a souligné @Mitch, ceci est spécifique au ThreadPool CLR. Si vous créez des fils directement, consultez les commentaires @Mitch et autres.
Vous pouvez le tester en utilisant ce code extrait:
private static void Main(string[] args)
{
int threadCount = 0;
try
{
for (int i = 0; i < int.MaxValue; i ++)
{
new Thread(() => Thread.Sleep(Timeout.Infinite)).Start();
threadCount ++;
}
}
catch
{
Console.WriteLine(threadCount);
Console.ReadKey(true);
}
}
Méfiez-vous du mode d'application 32 bits et 64 bits.
Je recommanderais d'exécuter la méthode ThreadPool.GetMaxThreads dans le débogage
ThreadPool.GetMaxThreads(out int workerThreadsCount, out int ioThreadsCount);
Documents et exemples: https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool.getmaxthreads?view=netframework-4.8