Share via


Threadpooling (C# und Visual Basic)

Ein Threadpool ist eine Threadauflistung, mit der verschiedene Aufgaben im Hintergrund ausgeführt werden können. (Hintergrundinformationen finden Sie unter Threading (C# und Visual Basic).) Auf diese Weise kann der primäre Thread asynchron andere Aufgaben ausführen.

Threadpools werden häufig in Serveranwendungen verwendet. Jede eingehende Anforderung wird einem Thread aus dem Threadpool zugewiesen, sodass die Anforderung asynchron verarbeitet werden kann, ohne den primären Thread zu binden oder die Verarbeitung von nachfolgenden Anforderungen zu verzögern.

Sobald ein Thread im Pool seine Aufgabe beendet hat, wird er wieder in die Threadwarteschlange eingereiht, von wo aus er wiederverwendet werden kann. Durch diese erneute Verwendung entfällt in Anwendungen der Aufwand zum Erstellen eines neuen Threads für jede Aufgabe.

Threadpools haben in der Regel eine maximale Anzahl von Threads. Wenn alle Threads aktiv sind, werden weitere Aufgaben in die Warteschlange gestellt, bis sie von wieder verfügbaren Threads verarbeitet werden können.

Sie können einen eigenen Threadpool implementieren, es ist jedoch einfacher, mit der ThreadPool-Klasse den von .NET Framework bereitgestellten Threadpool zu verwenden.

Beim Threadpooling rufen Sie die ThreadPool.QueueUserWorkItem-Methode mit einem Delegaten für die auszuführende Prozedur auf. Visual Basic bzw. C# erstellt dann den Thread und führt die Prozedur aus.

Beispiel zum Pooling von Threads

Das folgende Beispiel zeigt, wie Sie durch Pooling von Threads mehrere Tasks starten können.

Public Sub DoWork()
    ' Queue a task.
    System.Threading.ThreadPool.QueueUserWorkItem(
        New System.Threading.WaitCallback(AddressOf SomeLongTask))
    ' Queue another task.
    System.Threading.ThreadPool.QueueUserWorkItem(
        New System.Threading.WaitCallback(AddressOf AnotherLongTask))
End Sub
Private Sub SomeLongTask(ByVal state As Object)
    ' Insert code to perform a long task.
End Sub
Private Sub AnotherLongTask(ByVal state As Object)
    ' Insert code to perform another long task.
End Sub
public void DoWork()
{
    // Queue a task.
    System.Threading.ThreadPool.QueueUserWorkItem(
        new System.Threading.WaitCallback(SomeLongTask));
    // Queue another task.
    System.Threading.ThreadPool.QueueUserWorkItem(
        new System.Threading.WaitCallback(AnotherLongTask));
}

private void SomeLongTask(Object state)
{
    // Insert code to perform a long task.
}

private void AnotherLongTask(Object state)
{
    // Insert code to perform a long task.
}

Ein Vorteil des Poolings von Threads besteht darin, dass Sie Argumente in einem Statusobjekt an die Aufgabenprozedur übergeben können. Wenn die aufzurufende Prozedur mehr als ein Argument erfordert, können Sie eine Struktur oder eine Instanz einer Klasse in einen Object-Datentyp umwandeln.

Threadpoolparameter und -rückgabewerte

Die Rückgabe von Werten aus einem Threadpool-Thread ist nicht ganz einfach. Das Standardverfahren für die Rückgabe von Werten aus einem Funktionsaufruf ist nicht zulässig, da Sub-Prozeduren der einzige Prozedurtyp sind, der in der Warteschlange für einen Threadpool platziert werden kann. Eine Möglichkeit für die Angabe von Parametern und Rückgabewerten besteht darin, die Parameter, Rückgabewerte und Methoden mit einer Wrapperklasse zu umschließen, wie unter Parameter und Rückgabewerte für Multithreadprozeduren (C# und Visual Basic) beschrieben.

Ein einfacheres Verfahren ist die Verwendung der optionalen ByVal-Zustandsobjektvariable der QueueUserWorkItem-Methode. Wenn Sie diese Variable verwenden, um einen Verweis auf eine Instanz einer Klasse zu übergeben, können die Member der Instanz durch den Threadpool-Thread geändert und als Rückgabewerte verwendet werden.

Es mag zunächst nicht einleuchten, dass Sie ein Objekt ändern können, auf das eine Variable verweist, die als Wert übergeben wird. Dies ist möglich, da nur der Objektverweis als Wert übergeben wird. Wenn Sie die Member des Objekts ändern, auf das der Objektverweis verweist, werden die Änderungen auf die tatsächliche Klasseninstanz angewendet.

Strukturen können nicht für die Rückgabe von Werten in Statusobjekten verwendet werden. Da Strukturen Werttypen sind, wirken sich Änderungen, die der asynchrone Prozess durchführt, nicht auf die Member der ursprünglichen Struktur aus. Verwenden Sie Strukturen, um Parameter bereitzustellen, wenn keine Rückgabewerte benötigt werden.

Siehe auch

Aufgaben

Gewusst wie: Verwenden eines Threadpools (C# und Visual Basic)

Referenz

Threading (C# und Visual Basic)

Threadsynchronisierung (C# und Visual Basic)

QueueUserWorkItem

System.Threading

ThreadPool

Konzepte

Multithreadanwendungen (C# und Visual Basic)

Weitere Ressourcen

Gewusst wie: Übergabe einer Arbeitsaufgabe an den Threadpool mit Visual C#