Opciones de configuración de ejecución para subprocesos
En este artículo se detallan los valores que puede usar para configurar el subproceso en .NET.
Nota:
.NET 6 estandariza en el prefijo DOTNET_
en lugar de en COMPlus_
para las variables de entorno que configuran el comportamiento en tiempo de ejecución de .NET. Sin embargo, el prefijo COMPlus_
seguirá funcionando. Si usa una versión anterior del runtime de .NET, debe seguir usando el prefijo COMPlus_
para las variables de entorno.
Uso de todos los grupos de CPU en Windows
- En las máquinas que tienen varios grupos de CPU, esta opción configura si los componentes, como el grupo de subprocesos, usan todos los grupos de CPU o solo el grupo de CPU principal del proceso. Esta opción también afecta a lo que Environment.ProcessorCount devuelve.
- Cuando esta opción está habilitada, todos los grupos de CPU se usan y los subprocesos también se distribuyen automáticamente entre los grupos de CPU de forma predeterminada.
- Esta opción está habilitada de forma predeterminada en Windows 11 y versiones posteriores, y deshabilitada de forma predeterminada en Windows 10 y versiones anteriores. Para que esta opción surta efecto cuando está habilitada, el GC también debe configurarse para usar todos los grupos de CPU; para más información, consulte Grupos de CPU del GC.
Nombre de valor | Valores | |
---|---|---|
runtimeconfig.json | N/D | N/D |
Variable del entorno | COMPlus_Thread_UseAllCpuGroups o DOTNET_Thread_UseAllCpuGroups |
0 : deshabilitado.1 : habilitado. |
Asignación de subprocesos a grupos de CPU en Windows
- En las máquinas que tienen varios grupos de CPU y en las que todos ellos están en uso, esta opción configura si los subprocesos se distribuyen automáticamente entre los grupos de CPU.
- Cuando esta opción está habilitada, los nuevos subprocesos se asignan a un grupo de CPU de forma que intenta rellenar completamente un grupo de CPU que ya está en uso antes de usar un nuevo grupo de CPU.
- Esta opción está habilitada de forma predeterminada.
Nombre de valor | Valores | |
---|---|---|
runtimeconfig.json | N/D | N/D |
Variable del entorno | COMPlus_Thread_AssignCpuGroups o DOTNET_Thread_AssignCpuGroups |
0 : deshabilitado.1 : habilitado. |
Mínimo de subprocesos
- Especifica el número mínimo de subprocesos para el grupo de subprocesos de trabajo.
- Corresponde al método ThreadPool.SetMinThreads.
Nombre de valor | Valores | |
---|---|---|
runtimeconfig.json | System.Threading.ThreadPool.MinThreads |
Entero que representa el número mínimo de subprocesos. |
Propiedad de MSBuild | ThreadPoolMinThreads |
Entero que representa el número mínimo de subprocesos. |
Variable del entorno | N/D | N/D |
Ejemplos
Archivo runtimeconfig.json:
{
"runtimeOptions": {
"configProperties": {
"System.Threading.ThreadPool.MinThreads": 4
}
}
}
archivo runtimeconfig.template.json:
{
"configProperties": {
"System.Threading.ThreadPool.MinThreads": 4
}
}
Archivo del proyecto:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ThreadPoolMinThreads>4</ThreadPoolMinThreads>
</PropertyGroup>
</Project>
Máximo de subprocesos
- Especifica el número máximo de subprocesos para el grupo de subprocesos de trabajo.
- Corresponde al método ThreadPool.SetMaxThreads.
Nombre de valor | Valores | |
---|---|---|
runtimeconfig.json | System.Threading.ThreadPool.MaxThreads |
Entero que representa el número máximo de subprocesos. |
Propiedad de MSBuild | ThreadPoolMaxThreads |
Entero que representa el número máximo de subprocesos. |
Variable del entorno | N/D | N/D |
Ejemplos
Archivo runtimeconfig.json:
{
"runtimeOptions": {
"configProperties": {
"System.Threading.ThreadPool.MaxThreads": 20
}
}
}
archivo runtimeconfig.template.json:
{
"configProperties": {
"System.Threading.ThreadPool.MaxThreads": 20
}
}
Archivo del proyecto:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ThreadPoolMaxThreads>20</ThreadPoolMaxThreads>
</PropertyGroup>
</Project>
Grupo de subprocesos de Windows
- Para proyectos en Windows, configura si la administración de subprocesos del grupo de subprocesos se delega al grupo de subprocesos de Windows.
- Si omite esta configuración o la plataforma no es Windows, se usa en su lugar el grupo de subprocesos de .NET.
- Solo las aplicaciones publicadas con AOT nativo en Windows usan el grupo de subprocesos de Windows de forma predeterminada, para lo cual puede optar por usar el grupo de subprocesos de .NET en su lugar deshabilitando la configuración.
- El grupo de subprocesos de Windows puede funcionar mejor en algunos casos, como en los casos en los que el número mínimo de subprocesos está configurado en un valor alto o cuando la aplicación ya usa mucho el grupo de subprocesos de Windows. También puede haber casos en los que el grupo de subprocesos de .NET funcione mejor, como en el control de E/S pesado en máquinas más grandes. Es aconsejable comprobar las métricas de rendimiento al cambiar esta configuración.
- Algunas API no se admiten al usar el grupo de subprocesos de Windows, como ThreadPool.SetMinThreads, ThreadPool.SetMaxThreads y ThreadPool.BindHandle(SafeHandle). Los valores de configuración del grupo de subprocesos para subprocesos mínimos y máximos tampoco son efectivos. Una alternativa a ThreadPool.BindHandle(SafeHandle) es la clase ThreadPoolBoundHandle.
Nombre de valor | Valores | Versión introducida | |
---|---|---|---|
runtimeconfig.json | System.Threading.ThreadPool.UseWindowsThreadPool |
true : habilitado.false : deshabilitado. |
.NET 8 |
Propiedad de MSBuild | UseWindowsThreadPool |
true : habilitado.false : deshabilitado. |
.NET 8 |
Variable del entorno | DOTNET_ThreadPool_UseWindowsThreadPool |
1 : habilitado.0 : deshabilitado. |
.NET 8 |
Ejemplos
Archivo runtimeconfig.json:
{
"runtimeOptions": {
"configProperties": {
"System.Threading.ThreadPool.UseWindowsThreadPool": true
}
}
}
archivo runtimeconfig.template.json:
{
"configProperties": {
"System.Threading.ThreadPool.UseWindowsThreadPool": true
}
}
Archivo del proyecto:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<UseWindowsThreadPool>true</UseWindowsThreadPool>
</PropertyGroup>
</Project>
Inserción de subprocesos en respuesta al bloqueo de elementos de trabajo
En algunos casos, el grupo de subprocesos detecta elementos de trabajo que bloquean sus subprocesos. Para compensarlo, inserta más subprocesos. En .NET 6 y versiones posteriores, puede usar las opciones siguientes de configuración del entorno de ejecución para configurar la inserción de subprocesos en respuesta al bloqueo de elementos de trabajo. Actualmente, esta configuración solo surte efecto para los elementos de trabajo que esperan a que se complete otra tarea, como en los casos típicos de sincrónico sobre asincrónico.
Nombre de la opción de configuración runtimeconfig.json | Descripción | Versión introducida |
---|---|---|
System.Threading.ThreadPool.Blocking.ThreadsToAddWithoutDelay_ProcCountFactor |
Una vez alcanzado el recuento de subprocesos basado en MinThreads , este valor (una vez multiplicado por el número de procesadores) especifica cuántos subprocesos adicionales se pueden crear sin retraso. |
.NET 6 |
System.Threading.ThreadPool.Blocking.ThreadsPerDelayStep_ProcCountFactor |
Una vez alcanzado el recuento de subprocesos basado en ThreadsToAddWithoutDelay , este valor (una vez multiplicado por el número de procesadores) especifica después de cuántos subprocesos se agregaría un DelayStepMs adicional al retraso antes de crear cada nuevo hilo. |
.NET 6 |
System.Threading.ThreadPool.Blocking.DelayStepMs |
Una vez alcanzado el recuento de subprocesos basado en ThreadsToAddWithoutDelay , este valor especifica cuánto retraso adicional se agrega por cada ThreadsPerDelayStep subprocesos, que se aplicaría antes de crear cada nuevo subproceso. |
.NET 6 |
System.Threading.ThreadPool.Blocking.MaxDelayMs |
Una vez alcanzado el número de subprocesos basado en ThreadsToAddWithoutDelay , este valor especifica el retraso máximo que se debe usar antes de crear cada subproceso nuevo. |
.NET 6 |
System.Threading.ThreadPool.Blocking.IgnoreMemoryUsage |
De forma predeterminada, la tasa de inserción de subprocesos en respuesta al bloqueo está limitada por heurística que determina si hay suficiente memoria física disponible. En algunas situaciones, puede ser preferible insertar subprocesos más rápidamente incluso en situaciones de poca memoria. Puede deshabilitar la heurística de uso de memoria desactivando este conmutador. | .NET 7 |
Cómo surten efecto las opciones de configuración
- Una vez alcanzado el número de subprocesos basado en
MinThreads
, se pueden crear hastaThreadsToAddWithoutDelay
subprocesos adicionales sin retraso. - Después, antes de que se cree cada subproceso adicional, se induce un retraso, empezando por
DelayStepMs
. - Por cada
ThreadsPerDelayStep
subprocesos que se agregan con un retraso, se agrega unDelayStepMs
adicional al retraso. - El retraso no puede superar
MaxDelayMs
. - Los retrasos solo se inducen antes de crear subprocesos. Si los subprocesos ya están disponibles, se liberarían sin retraso para compensar el bloqueo de elementos de trabajo.
- También se utiliza el uso y los límites de la memoria física y, más allá de un umbral, el sistema cambia a una inserción de subprocesos más lenta.
Ejemplos
Archivo runtimeconfig.json:
{
"runtimeOptions": {
"configProperties": {
"System.Threading.ThreadPool.Blocking.ThreadsToAddWithoutDelay_ProcCountFactor": 5
}
}
}
archivo runtimeconfig.template.json:
{
"configProperties": {
"System.Threading.ThreadPool.Blocking.ThreadsToAddWithoutDelay_ProcCountFactor": 5
}
}
AutoreleasePool
para subprocesos administrados
Esta opción configura si cada subproceso administrado recibe un elemento NSAutoreleasePool implícito cuando se ejecuta en una plataforma macOS compatible.
Nombre de valor | Valores | Versión introducida | |
---|---|---|---|
runtimeconfig.json | System.Threading.Thread.EnableAutoreleasePool |
true o false |
.NET 6 |
Propiedad de MSBuild | AutoreleasePoolSupport |
true o false |
.NET 6 |
Variable del entorno | N/D | N/D | N/D |
Ejemplos
Archivo runtimeconfig.json:
{
"runtimeOptions": {
"configProperties": {
"System.Threading.Thread.EnableAutoreleasePool": true
}
}
}
archivo runtimeconfig.template.json:
{
"configProperties": {
"System.Threading.Thread.EnableAutoreleasePool": true
}
}
Archivo del proyecto:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AutoreleasePoolSupport>true</AutoreleasePoolSupport>
</PropertyGroup>
</Project>