Share via


スレッド プール (C# および Visual Basic)

スレッド プールとは、複数のタスクをバックグラウンドで実行するときに使用できるスレッドのコレクションです (詳細については、「スレッド処理 (C# および Visual Basic)」を参照してください)。 これにより、プライマリ スレッドは自由に他のタスクを非同期的に実行できます。

スレッド プールは、サーバー アプリケーションでよく使用されます。 受信した要求がそれぞれスレッド プールのスレッドに割り当てられるため、プライマリ スレッドを占有したり、後続の要求の処理を遅延させたりせずに、要求を非同期的に処理できます。

プール内のスレッドがタスクを完了すると、待機スレッドのキューに戻り、再使用できるようになります。 これで、アプリケーションは、タスクごとに新しいスレッドを作成するという負荷を避けることができます。

スレッド プールには、通常、最大数のスレッドがあります。 スレッドがすべてビジーである場合、追加のタスクは、スレッドが使用可能になり、処理できるようになるまでキューに置かれます。

スレッド プールは独自に実装できますが、.NET Framework が ThreadPool クラスを通じて提供するスレッド プールを使用する方が簡単です。

スレッド プールでは、実行するプロシージャのデリゲートを指定して ThreadPool.QueueUserWorkItem メソッドを呼び出すと、Visual Basic または C# がスレッドを作成し、プロシージャを実行します。

スレッド プールの例

スレッド プールを使用していくつかのタスクを起動する方法を次の例に示します。

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.
}

スレッド プールの利点の 1 つに、引数を状態オブジェクトでタスク プロシージャに渡すことができます。 呼び出し先のプロシージャが複数の引数を必要とする場合、構造体またはクラスのインスタンスを Object データ型にキャストできます。

スレッド プールのパラメーターと戻り値

スレッド プールのスレッドから値を返すのは簡単ではありません。 スレッド プールのキューに追加できるプロシージャは Sub プロシージャだけのため、関数呼び出しから値を返すという基本的な方法は使用できません。 パラメーターと戻り値を用意する方法の 1 つとして、パラメーター、戻り値、メソッドをラッパー クラスにラップするやり方があります。その方法については、「マルチスレッド プロシージャのパラメーターと戻り値 (C# および Visual Basic)」を参照してください。

この方法よりも簡単にパラメーターと戻り値を用意するには、QueueUserWorkItem メソッドの省略可能な ByVal 状態オブジェクト変数を使用します。 この変数を使用してクラスのインスタンスへの参照を渡すと、インスタンスのメンバーをスレッド プールのスレッドで変更し、戻り値として使用できます。

値によって渡される変数の参照先オブジェクトを変更できるかどうかが明確でない場合もあります。 これを変更できるのは、オブジェクト参照のみが値渡しされるからです。 オブジェクト参照によって参照されるオブジェクトのメンバーに変更を加えると、実際のクラス インスタンスに変更が適用されます。

状態オブジェクトの中の値を返すために構造体を使用することはできません。 構造体は値型であるため、非同期プロセスで変更しても、元の構造体のメンバーを変更することはできません。 構造体は、戻り値を必要としないときに、パラメーターを指定するために使用してください。

参照

処理手順

方法: スレッド プールを使用する (C# および Visual Basic)

参照

スレッド処理 (C# および Visual Basic)

スレッドの同期 (C# および Visual Basic)

QueueUserWorkItem

System.Threading

ThreadPool

概念

マルチスレッド アプリケーション (C# および Visual Basic)

その他の技術情報

Visual C# を使用してスレッド プールに作業項目を送信する方法