Der verwaltete Threadpool
Die System.Threading.ThreadPool-Klasse stellt einer Anwendung einen Pool von Arbeitsthreads bereit, die vom System verwaltet werden und Ihnen die Möglichkeit bieten, sich mehr auf Anwendungsaufgaben als auf die Threadverwaltung zu konzentrieren. Für kurze Aufgaben, bei denen Hintergrundverarbeitung erforderlich ist, bietet sich der verwaltete Threadpool als einfache Lösung für den Umgang mit mehreren Threads an. Die Verwendung des Threadpools ist ab Version 4 des Frameworks deutlich einfacher, da Sie Task- und Task<TResult>-Objekte erstellen können, die asynchrone Aufgaben auf Threads aus dem Threadpool ausführen.
Threadpoolthreads werden in .NET für viele Zwecke verwendet. Dazu gehören Task Parallel Library-Vorgänge (TPL), asynchrone E/A-Komplettierung, Timerrückrufe, registrierte Wartevorgänge, asynchrone Methodenaufrufe mithilfe von Delegaten und System.Net-Socketverbindungen.
Eigenschaften von Threadpools
Threadpoolthreads sind Hintergrundthreads. Jeder Thread verwendet die standardmäßige Stapelgröße, wird mit Standardpriorität ausgeführt und befindet sich im Multithread-Apartment. Sobald ein Thread im Threadpool seine Aufgabe abgeschlossen hat, wird er an eine Warteschlange von Threads zurückgegeben. Ab diesem Zeitpunkt kann er wiederverwendet werden. Aufgrund der Wiederverwendung müssen Anwendungen nicht für jede Aufgabe einen neuen Threads erstellen.
Pro Prozess gibt es nur einen Threadpool.
Ausnahmen in Threadpoolthreads
Nicht behandelte Ausnahmen in Threadpoolthreads beenden den Prozess. Für diese Regel gelten jedoch die folgenden drei Ausnahmen:
- In einem Threadpoolthread wird eine System.Threading.ThreadAbortException-Ausnahme ausgelöst, da Thread.Abort aufgerufen wurde.
- In einem Threadpoolthread wird eine System.AppDomainUnloadedException-Ausnahme ausgelöst, da die Anwendungsdomäne entladen wird.
- Der Prozess wurde durch die Common Language Runtime oder einen Hostprozess beendet.
Weitere Informationen finden Sie unter Ausnahmen in verwalteten Threads.
Maximale Anzahl von Threads im Threadpool
Die Anzahl von Vorgängen, die im Threadpool angereiht werden kann, wird nur durch den verfügbaren Arbeitsspeicher beschränkt. Allerdings schränkt der Threadpool die Anzahl von Threads ein, die gleichzeitig im Prozess aktiv sein können. Wenn alle Threadpoolthreads aktiv sind, werden zusätzliche Arbeitselemente eingereiht, bis Threads verfügbar sind, um diese auszuführen. Die Standardgröße des Threadpools für einen Prozess hängt von mehreren Faktoren ab, z. B. von der Größe des virtuellen Adressraums. Ein Prozess kann die ThreadPool.GetMaxThreads-Methode aufrufen, um die Anzahl der Threads zu bestimmen.
Sie können die maximale Anzahl von Threads mithilfe der ThreadPool.GetMaxThreads-Methode und der ThreadPool.SetMaxThreads-Methode steuern.
Hinweis
Code, der die Common Language Runtime hostet, kann die Größe mithilfe der ICorThreadpool::CorSetMaxThreads
-Methode festlegen.
Mindestwerte für den Threadpool
Der Threadpool stellt bei Bedarf neue Arbeitsthreads oder E/A-Abschlussthreads bereit, bis ein angegebener Mindestwert für jede Kategorie erreicht ist. Sie können die ThreadPool.GetMinThreads-Methode verwenden, um diese Mindestwerte abzurufen.
Hinweis
Wenn die Anforderungen niedrig sind, kann die tatsächliche Anzahl der Threads im Threadpool unterhalb der Mindestwerte liegen.
Wenn ein Minimum erreicht wird, kann der Threadpool weitere Threads erstellen oder warten, bis einige Aufgaben abgeschlossen sind. Der Threadpool erstellt und zerstört Arbeitsthreads, um den Durchsatz zu optimieren. Dieser ist als die Anzahl der Tasks definiert, die pro Zeiteinheit abgeschlossen werden. Bei zu wenigen Threads werden die verfügbaren Ressourcen möglicherweise nicht optimal genutzt, wohingegen bei zu vielen Threads Ressourcenkonflikte auftreten können.
Achtung
Sie können die ThreadPool.SetMinThreads-Methode verwenden, um die Mindestanzahl an Threads im Leerlauf zu erhöhen. Allerdings kann ein unnötiges Erhöhen dieses Wertes zu Leistungsproblemen führen. Wenn zu viele Aufgaben gleichzeitig gestartet werden, werden möglicherweise alle Aufgaben zu langsam ausgeführt. In den meisten Fällen erreicht der Threadpool mit dem eigenen Algorithmus für die Zuordnung von Threads eine bessere Leistung.
Verwenden des Threadpools
Der Threadpool kann am einfachsten über die Task Parallel Library (TPL) verwendet werden. Standardmäßig verwenden TPL-Typen wie Task und Task<TResult> Threadpoolthreads, um Aufgaben auszuführen.
Sie können den Threadpool auch verwenden, indem Sie in verwaltetem Code ThreadPool.QueueUserWorkItem aufrufen (oder ICorThreadpool::CorQueueUserWorkItem
in nicht verwaltetem Code) und einen System.Threading.WaitCallback-Delegaten übergeben, der die Methode darstellt, die die Aufgabe ausführt.
Eine andere Möglichkeit, den Threadpool zu verwenden, ist, Arbeitselemente, die mit einem Wartevorgang verknüpft sind, mit der ThreadPool.RegisterWaitForSingleObject-Methode in die Warteschlange zu stellen und ein System.Threading.WaitHandle zu übergeben, das bei einer Signalisierung oder einem Timeout die Methode aufruft, die vom System.Threading.WaitOrTimerCallback-Delegaten dargestellt wird. Threadpoolthreads werden zum Aufrufen von Rückrufmethoden verwendet.
Beispiele finden Sie auf den referenzierten API-Seiten.
Überspringen der Sicherheitsüberprüfungen
Der Threadpool stellt auch die ThreadPool.UnsafeQueueUserWorkItem-Methode und die ThreadPool.UnsafeRegisterWaitForSingleObject-Methode bereit. Verwenden Sie diese Methoden nur, wenn Sie sicher sind, dass der Stapel des Aufrufers irrelevant für die Sicherheitsüberprüfungen ist, die während der Ausführung der in der Warteschlange stehenden Aufgabe stattfinden. ThreadPool.QueueUserWorkItem und ThreadPool.RegisterWaitForSingleObject erfassen beide den Stapel des Aufrufers, der mit dem Stapel des Threadpoolthreads zusammengeführt wird, wenn der Thread beginnt, eine Aufgabe auszuführen. Wenn eine Sicherheitsüberprüfung erforderlich ist, muss der gesamte Stapel überprüft werden. Obwohl die Überprüfung Sicherheit gewährleistet, wird dadurch auch die Leistung beeinträchtigt.
Gründe, die gegen die Verwendung von Threadpools sprechen
In einigen Szenarios ist die Erstellung und Verwaltung eigener Threads der Verwendung von Threadpoolthreads vorzuziehen:
- Sie benötigen einen Vordergrundthread.
- Sie benötigen einen Thread mit einer bestimmten Priorität.
- Es gibt Aufgaben, die den Thread über einen längeren Zeitraum blockieren. Da die Anzahl der Threads im Threadpool begrenzt ist, kann eine hohe Anzahl blockierter Threadpoolthreads das Starten von Aufgaben verhindern.
- Sie müssen Threads in ein Singlethread-Apartment einfügen. Alle ThreadPool-Threads befinden sich im Multithread-Apartment.
- Dem Thread muss eine stabile Identität zugeordnet werden, oder ein Thread soll einer Aufgabe zugeordnet werden.
Weitere Informationen
- System.Threading.ThreadPool
- System.Threading.Tasks.Task
- System.Threading.Tasks.Task<TResult>
- Task Parallel Library (TPL)
- Gewusst wie: Zurückgeben eines Werts aus einer Aufgabe
- Threading Objects and Features (Threadingobjekte und -funktionen)
- Threads and Threading (Threads und Threading)
- Asynchronous File I/O
- Timer