Maximale Anzahl von Threads in einer .NET-App?

140

Wie viele Threads können maximal in einer C # -Anwendung erstellt werden? Und was passiert, wenn Sie diese Grenze erreichen? Wird eine Ausnahme geworfen?

John Saunders
quelle
Die Antwort wird unterschiedlich sein, wenn Sie auf der x64-VM oder der x86-VM laufen
Brian R. Bondy
In meiner Situation ist es x86, aber können Sie die Antwort für beide geben, falls jemand anderes sie benötigt?

Antworten:

145

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:

  • 1023 in Framework 4.0 (32-Bit-Umgebung)
  • 32767 in Framework 4.0 (64-Bit-Umgebung)
  • 250 pro Kern in Framework 3.5
  • 25 pro Kern in Framework 2.0

(Diese Zahlen können je nach Hardware und Betriebssystem variieren.)]

Mitch Wheat
quelle
13
Wie haben Sie das herausgefunden? Wissen Sie, was .NET 4.5 ist oder was 5.0 sein wird?
goodguys_activate
3
Sie können diesen Code verwenden, um die Anzahl abzurufen: int workerThreads; int finishPortThreads; ThreadPool.GetMaxThreads (out workerThreads, out vervollständigungPortThreads);
JALLRED
1
@MitchWheat Ich habe mich gefragt, weil der verlinkte Artikel nicht .NET behandelt, sondern einfach 'ol C.
pqsk
1
@ LoukMo: Wenn Sie keinen Thread erstellen können, ist Ihnen wahrscheinlich der Speicher ausgegangen! Ich habe es nicht ausprobiert, aber ich gehe davon aus, dass eine Speicherausnahme ausgelöst wird ...?
Mitch Wheat
1
@ Liam Der Link sollte jetzt behoben sein.
Eugene Komisarenko
26

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.

Antonio
quelle
9

Ich habe einen Test auf einem 64-Bit-System mit C # -Konsole durchgeführt. Die Ausnahme ist die Art des Speichermangels mit 2949-Threads.

Mir ist klar, dass wir einen Threading-Pool verwenden sollten, was ich auch tue, aber diese Antwort ist eine Antwort auf die Hauptfrage;)

MadApples
quelle
6

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.

Ian Boyd
quelle
Die Antwort ist , das System entscheiden zu lassen.
Ian Boyd
@ Ian: Ich habe dich abgelehnt, weil die gleiche Antwort neun Monate zuvor gegeben wurde.
John Saunders
11
Verknüpfung. Ich sehe keine Erwähnung des Thread-Pools als Antwort von irgendjemandem.
Ian Boyd
4

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.

Asche
quelle
Sie verwechseln CLR 2.0 und .NET 2.0 in Ihrem Kommentar zu .NET 3.5.
bzlm
Soweit ich weiß, hat SP1 für .NET 2.0 (Teil von .NET 3.5) die Standardeinstellung für Arbeitsthreads für Thread-Pools auf 250 pro CPU / Kern geändert.
Michael Damatov
0

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.

Yousha Aleayoub
quelle