用于线程的运行时配置选项
本文详细介绍了可用于在 .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_UseAllCpuGroups 或 DOTNET_Thread_UseAllCpuGroups |
0 - 禁用1 - 启用 |
将线程分配到 Windows 上的 CPU 组
- 在具有多个 CPU 组和使用所有 CPU 组的计算机上,此设置将配置线程是否自动分布在 CPU 组中。
- 启用此设置后,新线程将以一种方式分配到 CPU 组中,该方式尝试在利用新的 CPU 组之前充分填充已经在使用中的 CPU 组。
- 默认情况下,此设置处于启用状态。
设置名 | 值 | |
---|---|---|
runtimeconfig.json | 不可用 | 不可用 |
环境变量 | COMPlus_Thread_AssignCpuGroups 或 DOTNET_Thread_AssignCpuGroups |
0 - 禁用1 - 启用 |
最小线程数
- 指定工作线程池的最小线程数。
- 对应于 ThreadPool.SetMinThreads 方法。
设置名 | 值 | |
---|---|---|
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>
最大线程数
- 指定工作线程池的最大线程数。
- 对应于 ThreadPool.SetMaxThreads 方法。
设置名 | 值 | |
---|---|---|
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.SetMinThreads、ThreadPool.SetMaxThreads、ThreadPool.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 |
true 或 false |
.NET 6 |
MSBuild 属性 | AutoreleasePoolSupport |
true 或 false |
.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>