スレッド化のランタイム構成オプション

この記事では、.NET でスレッドを構成するために使用できる設定について詳しく説明します。

注意

.NET 6 では、.NET の実行時の動作を構成する環境変数のプレフィックスが、COMPlus_ ではなく DOTNET_ に標準化されています。 ただし、プレフィックス COMPlus_ は引き続き機能します。 以前のバージョンの .NET ランタイムを使用している場合は、環境変数に COMPlus_ プレフィックスをまだ使用する必要があります。

Windows 上のすべての CPU グループを使用する

  • この設定は、複数の CPU グループが存在するマシン上で、スレッド プールなどのコンポーネントがすべての CPU グループを使用するか、プロセスのプライマリ CPU グループのみを使用するかを構成します。 この設定は、Environment.ProcessorCount で返される内容にも影響します。
  • この設定を有効にすると、すべての CPU グループが使用され、スレッドも既定で CPU グループ全体に自動的に配布されます
  • この設定は、Windows 11 以降のバージョンでは既定で有効になり、Windows 10 以前のバージョンでは既定で無効になります。 有効化したときにこの設定が実行されるようにするには、すべての CPU グループを使用するように GC も構成する必要があります。詳細については、GC の CPU グループに関するページを参照してください。
設定の名前
runtimeconfig.json N/A N/A
環境変数 COMPlus_Thread_UseAllCpuGroups または DOTNET_Thread_UseAllCpuGroups 0 - 無効
1 - 有効

Windows 上の CPU グループにスレッドを割り当てる

  • 複数の CPU グループが存在し、すべての CPU グループが使用されているマシン上で、この設定は CPU グループ全体にスレッドを自動的に配布するかどうかを構成します。
  • この設定を有効にすると、新しいスレッドが CPU グループに割り当てられます。その際、新しい CPU グループを利用する前に、既に使用されている CPU グループへの完全な割り当てが行われます。
  • 既定では、この設定は有効になっています。
設定の名前
runtimeconfig.json N/A N/A
環境変数 COMPlus_Thread_AssignCpuGroups または DOTNET_Thread_AssignCpuGroups 0 - 無効
1 - 有効

最小スレッド数

  • ワーカー スレッド プールの最小スレッド数を指定します。
  • ThreadPool.SetMinThreads メソッドに対応します。
設定の名前
runtimeconfig.json System.Threading.ThreadPool.MinThreads 最小スレッド数を表す整数
MSBuild のプロパティ ThreadPoolMinThreads 最小スレッド数を表す整数
環境変数 N/A N/A

使用例

runtimeconfig.json ファイル:

{
   "runtimeOptions": {
      "configProperties": {
         "System.Threading.ThreadPool.MinThreads": 4
      }
   }
}

runtimeconfig.template.json ファイル:

{
   "configProperties": {
      "System.Threading.ThreadPool.MinThreads": 4
   }
}

プロジェクト ファイル:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <ThreadPoolMinThreads>4</ThreadPoolMinThreads>
  </PropertyGroup>

</Project>

最大スレッド数

  • ワーカー スレッド プールの最大スレッド数を指定します。
  • ThreadPool.SetMaxThreads メソッドに対応します。
設定の名前
runtimeconfig.json System.Threading.ThreadPool.MaxThreads 最大スレッド数を表す整数
MSBuild のプロパティ ThreadPoolMaxThreads 最大スレッド数を表す整数
環境変数 N/A N/A

使用例

runtimeconfig.json ファイル:

{
   "runtimeOptions": {
      "configProperties": {
         "System.Threading.ThreadPool.MaxThreads": 20
      }
   }
}

runtimeconfig.template.json ファイル:

{
   "configProperties": {
      "System.Threading.ThreadPool.MaxThreads": 20
   }
}

プロジェクト ファイル:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <ThreadPoolMaxThreads>20</ThreadPoolMaxThreads>
  </PropertyGroup>

</Project>

Windows スレッド プール

  • Windows 上のプロジェクトの場合、スレッド プールのスレッド管理を Windows スレッド プールに委任するかどうかを構成します。
  • この設定を省略した場合、またはプラットフォームが Windows でない場合は、代わりに .NET スレッド プールが使用されます。
  • Windows 上のネイティブ AOT を使用して発行されたアプリケーションのみが、既定で Windows スレッド プールを使用します。この場合、構成設定を無効にすることで、代わりに .NET スレッド プールを使用することを選択できます。
  • Windows スレッド プールの方がパフォーマンスが向上する場合があります。たとえば、スレッドの最小数が高い値に構成されている場合や、Windows スレッド プールがアプリによって既に頻繁に使用されている場合などです。 大規模なマシンでの大量の I/O 処理など、.NET スレッド プールの方がパフォーマンスが向上する場合もあります。 この構成設定を変更するときは、パフォーマンス メトリックを確認することをお勧めします。
  • ThreadPool.SetMinThreadsThreadPool.SetMaxThreadsThreadPool.BindHandle(SafeHandle) などの一部の API は、Windows スレッド プールを使用する場合はサポートされません。 最小および最大のスレッド数のスレッド プール構成設定も有効ではありません。 ThreadPool.BindHandle(SafeHandle) の代替となるのは ThreadPoolBoundHandle クラスです。
設定の名前 導入されたバージョン
runtimeconfig.json System.Threading.ThreadPool.UseWindowsThreadPool true - 有効
false - 無効
.NET 8
MSBuild のプロパティ UseWindowsThreadPool true - 有効
false - 無効
.NET 8
環境変数 DOTNET_ThreadPool_UseWindowsThreadPool 1 - 有効
0 - 無効
.NET 8

runtimeconfig.json ファイル:

{
   "runtimeOptions": {
      "configProperties": {
         "System.Threading.ThreadPool.UseWindowsThreadPool": true
      }
   }
}

runtimeconfig.template.json ファイル:

{
   "configProperties": {
      "System.Threading.ThreadPool.UseWindowsThreadPool": true
   }
}

プロジェクト ファイル:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <UseWindowsThreadPool>true</UseWindowsThreadPool>
  </PropertyGroup>

</Project>

作業項目のブロックに応じたスレッドの挿入

スレッド プールによって、スレッドをブロックする作業項目が検出される場合があります。 これを補うために、さらにスレッドが挿入されます。 .NET 6 以降では、次のランタイム構成設定を使用すると、作業項目のブロックに応じたスレッドの挿入を構成できます。 現在、これらの設定は、一般的な sync-over-async のケースのように、他のタスクの完了を待機する作業項目に対してのみ有効です。

runtimeconfig.json の設定名 説明 導入されたバージョン
System.Threading.ThreadPool.Blocking.ThreadsToAddWithoutDelay_ProcCountFactor この値 (プロセッサ数を乗じた後の値) には、MinThreads に基づくスレッド数に達した後、延期期間なしで追加のスレッドを作成できる数を指定します。 .NET 6
System.Threading.ThreadPool.Blocking.ThreadsPerDelayStep_ProcCountFactor この値 (プロセッサ数を乗じた後の値) には、ThreadsToAddWithoutDelay に基づくスレッド数に達した後、新しいスレッドが作成されるまでの延期期間に、さらに DelayStepMs を追加するスレッドの数を指定します。 .NET 6
System.Threading.ThreadPool.Blocking.DelayStepMs この値には、ThreadsToAddWithoutDelay に基づくスレッド数に達した後、ThreadsPerDelayStep スレッドごとに追加する延期期間を指定します。これは、個々の新しいスレッドが作成される前に適用されます。 .NET 6
System.Threading.ThreadPool.Blocking.MaxDelayMs この値には、ThreadsToAddWithoutDelay に基づくスレッド数に達した後、個々の新しいスレッドが作成される前に使用する最大の延期期間を指定します。 .NET 6
System.Threading.ThreadPool.Blocking.IgnoreMemoryUsage 既定では、ブロックに応じたスレッドの挿入の比率は、使用可能な物理メモリが十分あるかどうかを判断するヒューリスティックによって制限されます。 場合によっては、メモリが少ない状況でも、より迅速にスレッドを挿入した方がよいことがあります。 このスイッチをオフにすると、メモリ使用量のヒューリスティックを無効にすることができます。 .NET 7

構成設定が反映されるしくみ

  • MinThreads に基づくスレッド数に達した後、延期期間なしで最大 ThreadsToAddWithoutDelay 個の追加スレッドを作成できます。
  • その後、個々の追加スレッドが作成される前に、DelayStepMs から始まる延期期間が発生します。
  • 延期期間と共に追加された ThreadsPerDelayStep スレッドごとに、さらに DelayStepMs が延期期間に追加されます。
  • 延期期間が MaxDelayMs を超えることはできません。
  • 延期期間はスレッドを作成する前にのみ発生します。 スレッドが既に使用可能な場合は、ブロックしている作業項目を補うために、延期期間なしで解放されます。
  • 物理メモリの使用量と制限も使用され、しきい値を超えると、システムはより低速なスレッドの挿入に切り替えられます。

使用例

runtimeconfig.json ファイル:

{
   "runtimeOptions": {
      "configProperties": {
         "System.Threading.ThreadPool.Blocking.ThreadsToAddWithoutDelay_ProcCountFactor": 5
      }
   }
}

runtimeconfig.template.json ファイル:

{
   "configProperties": {
      "System.Threading.ThreadPool.Blocking.ThreadsToAddWithoutDelay_ProcCountFactor": 5
   }
}

マネージド スレッド用の AutoreleasePool

このオプションは、サポートされている macOS プラットフォームで実行されたときに、各マネージド スレッドが暗黙的な NSAutoreleasePool を受け取るかどうかを構成します。

設定の名前 導入されたバージョン
runtimeconfig.json System.Threading.Thread.EnableAutoreleasePool true または false .NET 6
MSBuild のプロパティ AutoreleasePoolSupport true または false .NET 6
環境変数 N/A 該当なし N/A

使用例

runtimeconfig.json ファイル:

{
   "runtimeOptions": {
      "configProperties": {
         "System.Threading.Thread.EnableAutoreleasePool": true
      }
   }
}

runtimeconfig.template.json ファイル:

{
   "configProperties": {
      "System.Threading.Thread.EnableAutoreleasePool": true
   }
}

プロジェクト ファイル:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <AutoreleasePoolSupport>true</AutoreleasePoolSupport>
  </PropertyGroup>

</Project>