ThreadPool クラス

定義

タスクの実行、作業項目のポスト、非同期 I/O の処理、他のスレッドの代理で行う待機、およびタイマーの処理に使用できるスレッドのプールを提供します。

public ref class ThreadPool abstract sealed
public ref class ThreadPool sealed
public static class ThreadPool
public sealed class ThreadPool
type ThreadPool = class
Public Class ThreadPool
Public NotInheritable Class ThreadPool
継承
ThreadPool

次の例では、メイン アプリケーション スレッドは、スレッド プール スレッドで実行する名前 ThreadProc のメソッドをキューに入れ、1 秒間スリープしてから終了します。 メソッドは ThreadProc 単にメッセージを表示します。

using namespace System;
using namespace System::Threading;

ref class Example
{
public:

   // This thread procedure performs the task.
   static void ThreadProc(Object^ stateInfo)
   {
      
      // No state object was passed to QueueUserWorkItem, so stateInfo is 0.
      Console::WriteLine( "Hello from the thread pool." );
   }
};

int main()
{
   // Queue the task.
   ThreadPool::QueueUserWorkItem(gcnew WaitCallback(Example::ThreadProc));

   Console::WriteLine("Main thread does some work, then sleeps.");
   
   Thread::Sleep(1000);
   Console::WriteLine("Main thread exits.");
   return 0;
}
// The example displays output like the following:
//       Main thread does some work, then sleeps.
//       Hello from the thread pool.
//       Main thread exits.
using System;
using System.Threading;

public class Example 
{
    public static void Main() 
    {
        // Queue the task.
        ThreadPool.QueueUserWorkItem(ThreadProc);
        Console.WriteLine("Main thread does some work, then sleeps.");
        Thread.Sleep(1000);

        Console.WriteLine("Main thread exits.");
    }

    // This thread procedure performs the task.
    static void ThreadProc(Object stateInfo) 
    {
        // No state object was passed to QueueUserWorkItem, so stateInfo is null.
        Console.WriteLine("Hello from the thread pool.");
    }
}
// The example displays output like the following:
//       Main thread does some work, then sleeps.
//       Hello from the thread pool.
//       Main thread exits.
Imports System.Threading

Public Module Example
    Public Sub Main()
        ' Queue the work for execution.
        ThreadPool.QueueUserWorkItem(AddressOf ThreadProc)
        
        Console.WriteLine("Main thread does some work, then sleeps.")

        Thread.Sleep(1000)

        Console.WriteLine("Main thread exits.")
    End Sub

    ' This thread procedure performs the task.
    Sub ThreadProc(stateInfo As Object)
        ' No state object was passed to QueueUserWorkItem, so stateInfo is null.
        Console.WriteLine("Hello from the thread pool.")
    End Sub
End Module
' The example displays output like the following:
'       Main thread does some work, then sleeps.
'       Hello from the thread pool.
'       Main thread exits.

メソッドの呼び出しを Thread.Sleep コメントアウトすると、メイン スレッドはスレッド プール スレッドでメソッドを実行する前に終了します。 スレッド プールはバックグラウンド スレッドを使用します。これは、すべてのフォアグラウンド スレッドが終了してもアプリケーションの実行を維持しません。 (これは、競合状態の簡単な例です)。

注釈

多くのアプリケーションでは、スリープ状態で多くの時間を費やし、イベントが発生するのを待つスレッドが作成されます。 他のスレッドは、変更または更新の状態情報をポーリングするために定期的に目覚めるためだけにスリープ状態になる場合があります。 スレッド プールを使用すると、システムによって管理されるワーカー スレッドのプールをアプリケーションに提供することで、スレッドをより効率的に使用できます。 スレッド プール スレッドを使用する操作の例を次に示します。

  • タスクを Task 非同期的に実行するオブジェクトまたは Task<TResult> オブジェクトを作成すると、既定では、タスクはスレッド プール スレッドで実行されるようにスケジュールされます。

  • 非同期タイマーはスレッド プールを使用します。 スレッド プール スレッドは、クラスからコールバックを System.Threading.Timer 実行し、クラスからイベントを System.Timers.Timer 発生させます。

  • 登録済みの待機ハンドルを使用すると、システム スレッドは待機ハンドルの状態を監視します。 待機操作が完了すると、スレッド プールのワーカー スレッドが対応するコールバック関数を実行します。

  • メソッドを QueueUserWorkItem 呼び出して、スレッド プール スレッドで実行するメソッドをキューに入れるとき。 これを行うには、メソッドにデリゲートを WaitCallback 渡します。 デリゲートに署名がある

    void WaitCallback(Object state)  
    
    Sub WaitCallback(state As Object)  
    

    where state は、デリゲートによって使用されるデータを含むオブジェクトです。 メソッドを呼び出すことで、実際のデータをデリゲートに QueueUserWorkItem(WaitCallback, Object) 渡すことができます。

注意

マネージド スレッド プール内のスレッドはバックグラウンド スレッドです。 つまり、それらの IsBackground プロパティは true. つまり、すべてのフォアグラウンド スレッドが ThreadPool 終了しても、スレッドはアプリケーションを実行し続けなくなります。

重要

スレッド プールがスレッドを再利用しても、スレッド ローカル ストレージまたは属性で ThreadStaticAttribute マークされているフィールド内のデータは消去されません。 そのため、メソッドがスレッド ローカル ストレージまたは属性でマークされているフィールドを ThreadStaticAttribute 調べると、見つかる値は、スレッド プール スレッドの以前の使用から残される可能性があります。

待機操作に関連しない作業項目をスレッド プールにキューに入れることもできます。 スレッド プール内のスレッドによって作業項目を処理するように要求するには、メソッドを QueueUserWorkItem 呼び出します。 このメソッドは、スレッド プールから選択されたスレッドによって呼び出されるメソッドまたはデリゲートへの参照をパラメーターとして受け取ります。 作業項目がキューに入った後で取り消す方法はありません。

タイマー キュー タイマーと登録済み待機操作では、スレッド プールも使用されます。 コールバック関数はスレッド プールにキューに入れられます。

プロセスごとに 1 つのスレッド プールがあります。 .NET Framework 4 以降では、プロセスのスレッド プールの既定のサイズは、仮想アドレス空間のサイズなど、いくつかの要素によって決まります。 スレッドの数は、プロセスで GetMaxThreads メソッドを呼び出せば確認できます。 スレッド プール内のスレッドの数は、メソッドを使用して SetMaxThreads 変更できます。 各スレッドは既定のスタック サイズを使用し、既定の優先度で実行されます。

注意

.NET Frameworkをホストするアンマネージ コードは、mscoree.h ファイルで定義されている関数をCorSetMaxThreads使用してスレッド プールのサイズを変更できます。

スレッド プールは、各カテゴリの最大値に達するまで、新しいワーカー スレッドまたは I/O 完了スレッドをオンデマンドで提供します。 最大に達すると、スレッド プールはそのカテゴリに追加のスレッドを作成するか、一部のタスクが完了するまで待機できます。 .NET Framework 4 以降では、スループットを最適化するために、スレッド プールでワーカー スレッドの作成と破棄が行われます。スループットは、タスクの単位時間あたりの完了数として定義されます。 スレッドが少なすぎると使用可能なリソースが最適に使用されない可能性があり、スレッドが多すぎるとリソースの競合が増える可能性があります。

注意

要求が少ないときは、スレッド プールの実際のスレッド数が最小値を下回る場合があります。

これらの最小値は、GetMinThreads メソッドを使用して取得できます。

注意事項

このメソッドを SetMinThreads 使用して、スレッドの最小数を増やすことができます。 ただし、これらの値を必要以上に大きくすると、パフォーマンスの問題が発生する可能性があります。 同時に開始するタスクの数が多すぎる場合は、すべてのタスクで処理速度が低下する可能性があります。 ほとんどの場合、スレッドを割り当てるためのスレッド プール独自のアルゴリズムを使用することでスレッド プールのパフォーマンスが向上します。

プロパティ

CompletedWorkItemCount

これまでに処理された作業項目の数を取得します。

PendingWorkItemCount

処理するキューに置かれた現在の作業項目の数を取得します。

ThreadCount

現在存在しているスレッド プールのスレッド数を取得します。

メソッド

BindHandle(IntPtr)
互換性のために残されています。
互換性のために残されています。

オペレーティング システム ハンドルを ThreadPool にバインドします。

BindHandle(SafeHandle)

オペレーティング システム ハンドルを ThreadPool にバインドします。

GetAvailableThreads(Int32, Int32)

スレッド プール スレッドの最大数 (GetMaxThreads(Int32, Int32) メソッドから返される) と現在アクティブなスレッドの数との差を取得します。

GetMaxThreads(Int32, Int32)

同時にアクティブにできるスレッド プールへの要求の数を取得します。 この数を超える要求はすべて、スレッド プール スレッドが使用可能になるまでキューに置かれたままになります。

GetMinThreads(Int32, Int32)

スレッドがオンデマンドで (新しい要求の発生ごとに) 作成するスレッド プールの数を取得します。この数を超えると、スレッドの作成と破棄を管理するためのアルゴリズムに切り替わります。

QueueUserWorkItem(WaitCallback)

メソッドを実行するためのキューに置きます。 メソッドは、スレッド プール スレッドが使用可能になったときに実行されます。

QueueUserWorkItem(WaitCallback, Object)

実行するためのキューにメソッドを置き、そのメソッドが使用するデータを含んだオブジェクトを指定します。 メソッドは、スレッド プール スレッドが使用可能になったときに実行されます。

QueueUserWorkItem<TState>(Action<TState>, TState, Boolean)

実行用に Action<T> デリゲートで指定したメソッドをキューに入れ、メソッドで使うデータを指定します。 メソッドは、スレッド プール スレッドが使用可能になったときに実行されます。

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean)

ミリ秒単位のタイムアウトとして 32 ビット符号付き整数を指定して、WaitHandle を待機するデリゲートを登録します。

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int64, Boolean)

64 ビット符号付き整数でミリ秒単位のタイムアウトを指定して、WaitHandle を待機するデリゲートを登録します。

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, TimeSpan, Boolean)

TimeSpan 値をタイムアウトとして指定して、WaitHandle を待機するデリゲートを登録します。

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, UInt32, Boolean)

32 ビット符号なし整数でミリ秒単位のタイムアウトを指定して、WaitHandle を待機するデリゲートを登録します。

SetMaxThreads(Int32, Int32)

同時にアクティブにできるスレッド プールへの要求の数を設定します。 この数を超える要求はすべて、スレッド プール スレッドが使用可能になるまでキューに置かれたままになります。

SetMinThreads(Int32, Int32)

スレッドがオンデマンドで (新しい要求の発生ごとに) 作成するスレッド プールの数を設定します。この数を超えると、スレッドの作成と破棄を管理するためのアルゴリズムに切り替わります。

UnsafeQueueNativeOverlapped(NativeOverlapped*)

重複した I/O 操作を、実行するためのキューに置きます。

UnsafeQueueUserWorkItem(IThreadPoolWorkItem, Boolean)

指定された作業項目オブジェクトをスレッド プールのキューに入れます。

UnsafeQueueUserWorkItem(WaitCallback, Object)

指定したデリゲートをスレッド プールのキューに置きます。ただし、コール スタックをワーカー スレッドに反映しません。

UnsafeQueueUserWorkItem<TState>(Action<TState>, TState, Boolean)

実行用に Action<T> デリゲートで指定したメソッドをキューに入れ、そのメソッドで使用するデータを含んだオブジェクトを指定します。 メソッドは、スレッド プール スレッドが使用可能になったときに実行されます。

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean)

ミリ秒単位のタイムアウトとして 32 ビット符号付き整数を使用して、WaitHandle を待機するデリゲートを登録します。 このメソッドはコール スタックをワーカー スレッドに反映しません。

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int64, Boolean)

64 ビット符号付き整数でミリ秒単位のタイムアウトを指定して、WaitHandle を待機するデリゲートを登録します。 このメソッドはコール スタックをワーカー スレッドに反映しません。

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, TimeSpan, Boolean)

TimeSpan 値をタイムアウトとして指定して、WaitHandle を待機するデリゲートを登録します。このメソッドはコール スタックをワーカー スレッドに反映しません。

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, UInt32, Boolean)

32 ビット符号なし整数でミリ秒単位のタイムアウトを指定して、WaitHandle を待機するデリゲートを登録します。 このメソッドはコール スタックをワーカー スレッドに反映しません。

適用対象

スレッド セーフ

この型はスレッド セーフです。

こちらもご覧ください