用于线程的运行时配置选项

本文详细介绍了可用于在 .NET 中配置线程的设置。

注意

.NET 6 为用于配置 .NET 运行时行为的环境变量标准化前缀 DOTNET_ 而不是 COMPlus_。 但是,COMPlus_ 前缀仍将继续正常工作。 如果使用的是早期版本的 .NET 运行时,则环境变量仍应该使用 COMPlus_ 前缀。

在 Windows 上使用所有 CPU 组

  • 在具有多个 CPU 组的计算机上,此设置将配置线程池等组件是使用所有 CPU 组还是仅使用进程的主 CPU 组。 该设置还会影响 Environment.ProcessorCount 返回的内容。
  • 启用此设置后,将使用所有 CPU 组,并且默认情况下,线程也会自动分布在 CPU 组中
  • 此设置默认在 Windows 11 及更高版本上启用,默认情况下在 Windows 10 及更低版本上禁用。 为了使此设置在启用时生效,还必须将 GC 配置为使用所有 CPU 组;有关详细信息,请参阅 GC CPU 组
设置名
runtimeconfig.json 不可用 不可用
环境变量 COMPlus_Thread_UseAllCpuGroupsDOTNET_Thread_UseAllCpuGroups 0 - 禁用
1 - 启用

将线程分配到 Windows 上的 CPU 组

  • 在具有多个 CPU 组和使用所有 CPU 组的计算机上,此设置将配置线程是否自动分布在 CPU 组中。
  • 启用此设置后,新线程将以一种方式分配到 CPU 组中,该方式尝试在利用新的 CPU 组之前充分填充已经在使用中的 CPU 组。
  • 默认情况下,此设置处于启用状态。
设置名
runtimeconfig.json 不可用 不可用
环境变量 COMPlus_Thread_AssignCpuGroupsDOTNET_Thread_AssignCpuGroups 0 - 禁用
1 - 启用

最小线程数

设置名
runtimeconfig.json System.Threading.ThreadPool.MinThreads 一个表示最小线程数的整数
MSBuild 属性 ThreadPoolMinThreads 一个表示最小线程数的整数
环境变量 不可用 不可用

示例

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>

最大线程数

设置名
runtimeconfig.json System.Threading.ThreadPool.MaxThreads 一个表示最大线程数的整数
MSBuild 属性 ThreadPoolMaxThreads 一个表示最大线程数的整数
环境变量 不可用 不可用

示例

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 线程池时。 某些情况下,.NET 线程池的性能更好,例如在较大的计算机上执行大量 I/O 处理时。 建议在更改此配置设置时检查性能指标。
  • 使用 Windows 线程池(例如 ThreadPool.SetMinThreadsThreadPool.SetMaxThreadsThreadPool.BindHandle(SafeHandle))时不支持某些 API。 最小和最大线程的线程池配置设置也无效。 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 truefalse .NET 6
MSBuild 属性 AutoreleasePoolSupport truefalse .NET 6
环境变量 不可用 不可用 不可用

示例

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>