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

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

在 Windows 上使用所有 CPU 组

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

将线程分配到 Windows 上的 CPU 组

  • 在使用多个 CPU 组和 所有 CPU 组的计算机上,此设置将配置线程是否自动分布在 CPU 组中。
  • 启用此设置后,新线程会以尝试在使用新 CPU 组之前完全填充已使用的 CPU 组的方式分配给 CPU 组。
  • 默认情况下,此设置处于启用状态。
设置名称 价值观
runtimeconfig.json N/A N/A
环境变量 DOTNET_Thread_AssignCpuGroups 0 - 禁用
1 - 启用

最小线程数

设置名称 价值观
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>

最大线程数

设置名称 价值观
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 线程池时。 在某些情况下,.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+ 中,可以使用以下 运行时配置 设置来配置线程注入,以响应阻止工作项。 目前,这些设置仅对等待其他任务完成的工作项生效,例如在典型的 同步过度同步 情况下。

runtimeconfig.json 设置名称 Description 引入的版本
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
环境变量 N/A 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>