Wie viele Threads können maximal in einer C # -Anwendung erstellt werden? Und was passiert, wenn Sie diese Grenze erreichen? Wird eine Ausnahme geworfen?
Wie viele Threads können maximal in einer C # -Anwendung erstellt werden? Und was passiert, wenn Sie diese Grenze erreichen? Wird eine Ausnahme geworfen?
Antworten:
Es gibt keine inhärente Grenze. Die maximale Anzahl von Threads wird durch die Menge der verfügbaren physischen Ressourcen bestimmt. Einzelheiten finden Sie in diesem Artikel von Raymond Chen .
Wenn Sie nach der maximalen Anzahl von Threads fragen müssen, machen Sie wahrscheinlich etwas falsch.
[ Update : Nur aus Interesse: Standard-Thread-Anzahl von .NET-Thread-Pools:
(Diese Zahlen können je nach Hardware und Betriebssystem variieren.)]
Mitch hat recht. Es hängt von den Ressourcen (Speicher) ab.
Obwohl der Artikel von Raymond Windows-Threads und nicht C # -Threads gewidmet ist, gilt dieselbe Logik (C # -Threads werden Windows-Threads zugeordnet).
Da wir uns jedoch in C # befinden, müssen wir zwischen "gestarteten" und "nicht gestarteten" Threads unterscheiden, wenn wir vollständig präzise sein möchten. Nur gestartete Threads reservieren tatsächlich Stapelspeicherplatz (wie zu erwarten). Nicht gestartete Threads weisen nur die Informationen zu, die für ein Thread-Objekt erforderlich sind (Sie können den Reflektor verwenden, wenn Sie an den tatsächlichen Elementen interessiert sind).
Sie können es tatsächlich selbst testen, vergleichen Sie:
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)
{
}
}
mit:
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)
{
}
}
Setzen Sie einen Haltepunkt in die Ausnahme (natürlich nicht genügend Speicher) in VS, um den Wert des Zählers anzuzeigen. Es gibt natürlich einen sehr signifikanten Unterschied.
Sie sollten den Thread-Pool (oder asynchrone Delgates, die wiederum den Thread-Pool verwenden) verwenden, damit das System entscheiden kann, wie viele Threads ausgeführt werden sollen.
Jeff Richter in CLR über C #:
"Mit Version 2.0 der CLR beträgt die maximale Anzahl von Worker-Threads standardmäßig 25 pro CPU im Computer und die maximale Anzahl von E / A-Threads standardmäßig 1000. Ein Limit von 1000 ist praktisch überhaupt kein Limit."
Beachten Sie, dass dies auf .NET 2.0 basiert. Dies hat sich möglicherweise in .NET 3.5 geändert.
[Bearbeiten] Wie @Mitch hervorhob, ist dies spezifisch für den CLR-ThreadPool. Wenn Sie Threads direkt erstellen, lesen Sie die Kommentare zu @Mitch und anderen.
Sie können es mit diesem Code testen :
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);
}
}
Achten Sie auf den 32-Bit- und 64-Bit-Anwendungsmodus.
Ich würde empfehlen, die ThreadPool.GetMaxThreads-Methode im Debug auszuführen
ThreadPool.GetMaxThreads(out int workerThreadsCount, out int ioThreadsCount);
Dokumente und Beispiele: https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool.getmaxthreads?view=netframework-4.8