スレッド プール

更新 : 2007 年 11 月

スレッド プールは、タスクをキューに追加し、スレッドが作成されると自動的にタスクを起動するマルチスレッドの形式です。スレッド プールでは、実行するプロシージャのデリゲートを指定して ThreadPool.QueueUserWorkItem メソッドを呼び出すと、Visual Basic がスレッドを作成し、プロシージャを実行します。

スレッド プールの例

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

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
Sub SomeLongTask(ByVal state As Object)
    ' Insert code to perform a long task.
End Sub
Sub AnotherLongTask(ByVal state As Object)
    ' Insert code to perform another long task.
End Sub

スレッド プールは、各スレッドのプロパティを個別に設定せずに複数のタスクを起動するときに役立ちます。各スレッドは、既定のスタック サイズとプロパティで起動します。既定では、1 つのシステム プロセッサにつき、スレッド プールのスレッドを 25 個まで実行できます。この制限を超えてスレッドをキューに追加することもできますが、このスレッドは他のスレッドが終了するまで起動しません。

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

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

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

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

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

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

参照

概念

Visual Basic での高度なマルチスレッド処理

マルチスレッド アプリケーション

スレッドの同期

フォームとコントロールでのマルチスレッド

参照

QueueUserWorkItem

System.Threading

SyncLock ステートメント