Qual è il numero massimo di thread che è possibile creare in un'applicazione C #? E cosa succede quando si raggiunge questo limite? Viene generata un'eccezione di qualche tipo?
Qual è il numero massimo di thread che è possibile creare in un'applicazione C #? E cosa succede quando si raggiunge questo limite? Viene generata un'eccezione di qualche tipo?
Risposte:
Non esiste un limite intrinseco. Il numero massimo di thread è determinato dalla quantità di risorse fisiche disponibili. Vedi questo articolo di Raymond Chen per dettagli.
Se devi chiedere qual è il numero massimo di thread, probabilmente stai facendo qualcosa di sbagliato.
[ Aggiornamento : solo per interesse: numero di thread predefiniti del pool di thread .NET:
(Questi numeri possono variare a seconda dell'hardware e del sistema operativo)]
Mitch ha ragione. Dipende dalle risorse (memoria).
Sebbene l'articolo di Raymond sia dedicato ai thread di Windows, non ai thread C #, la logica si applica allo stesso modo (i thread C # sono associati ai thread di Windows).
Tuttavia, poiché siamo in C #, se vogliamo essere completamente precisi, dobbiamo distinguere tra thread "avviati" e "non avviati". Solo i thread avviati in realtà riservano spazio nello stack (come potevamo aspettarci). I thread non avviati allocano solo le informazioni richieste da un oggetto thread (è possibile utilizzare il riflettore se interessati ai membri effettivi).
Puoi effettivamente testarlo da solo, confrontare:
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)
{
}
}
con:
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)
{
}
}
Inserisci un breakpoint nell'eccezione (memoria insufficiente, ovviamente) in VS per vedere il valore del contatore. C'è una differenza molto significativa, ovviamente.
Dovresti usare il pool di thread (o i delegati asincroni, che a loro volta utilizzano il pool di thread) in modo che il sistema possa decidere quanti thread devono essere eseguiti.
Jeff Richter in CLR via C #:
"Con la versione 2.0 del CLR, il numero massimo di thread di lavoro è impostato automaticamente su 25 per CPU nella macchina e il numero massimo di thread di I / O è impostato automaticamente su 1000. Un limite di 1000 non è effettivamente un limite."
Nota che si basa su .NET 2.0. Questo potrebbe essere cambiato in .NET 3.5.
[Modifica] Come sottolineato da @Mitch, questo è specifico per il ThreadPool CLR. Se stai creando discussioni vedi direttamente i commenti di @Mitch e di altri.
Puoi testarlo usando questo codice snipped:
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);
}
}
Attenzione alle modalità di applicazione a 32 e 64 bit.
Consiglierei di eseguire il metodo ThreadPool.GetMaxThreads nel debug
ThreadPool.GetMaxThreads(out int workerThreadsCount, out int ioThreadsCount);
Documenti ed esempi: https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool.getmaxthreads?view=netframework-4.8