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 して変更できます。 各スレッドは既定のスタック サイズを使用し、既定の優先度で実行されます。

Note

.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 を待機するデリゲートを登録します。 このメソッドはコール スタックをワーカー スレッドに反映しません。

適用対象

スレッド セーフ

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

こちらもご覧ください