Opções de configuração de execução para threading
Este artigo detalha as configurações que você pode usar para configurar o threading no .NET.
Observação
O .NET 6 usa o prefixo DOTNET_
como padrão em vez de COMPlus_
para variáveis de ambiente que configuram o comportamento de tempo de execução do .NET. No entanto, o prefixo COMPlus_
continuará funcionando. Se você estiver usando uma versão anterior do runtime do .NET, continue usando o prefixo COMPlus_
para variáveis de ambiente.
Usar todos os grupos de CPU no Windows
- Em computadores que têm vários grupos de CPU, essa configuração define se os componentes como o pool de threads usam todos os grupos de CPU ou apenas o grupo de CPU primário do processo. A configuração também afeta o que Environment.ProcessorCount retorna.
- Quando essa configuração está habilitada, todos os grupos de CPU são usados e os threads também são distribuídos automaticamente entre grupos de CPU por padrão.
- Essa configuração é habilitada por padrão no Windows 11 e versões posteriores e desabilitada por padrão no Windows 10 e versões anteriores. Para que essa configuração entre em vigor quando habilitada, o GC também deve ser configurado para usar todos os grupos de CPU. Para obter mais informações, consulte Grupos de CPU do GC.
Nome da configuração | Valores | |
---|---|---|
runtimeconfig.json | N/D | N/D |
Variável de ambiente | COMPlus_Thread_UseAllCpuGroups ou DOTNET_Thread_UseAllCpuGroups |
0 -desabilitado1 – Habilitado |
Atribuir threads a grupos de CPU no Windows
- Em computadores que têm vários grupos de CPU e todos os grupos de CPU estão sendo usados, essa configuração define se os threads são distribuídos automaticamente entre grupos de CPU.
- Quando essa configuração está habilitada, novos threads são atribuídos a um grupo de CPU de uma maneira que tenta preencher totalmente um grupo de CPU que já está em uso antes de utilizar um novo grupo de CPU.
- Essa configuração é habilitada por padrão.
Nome da configuração | Valores | |
---|---|---|
runtimeconfig.json | N/D | N/D |
Variável de ambiente | COMPlus_Thread_AssignCpuGroups ou DOTNET_Thread_AssignCpuGroups |
0 -desabilitado1 – Habilitado |
Mínimo de thread
- Especifica o número mínimo de threads para o pool de threads de trabalho.
- Corresponde ao método ThreadPool.SetMinThreads.
Nome da configuração | Valores | |
---|---|---|
runtimeconfig.json | System.Threading.ThreadPool.MinThreads |
Um inteiro que representa o número mínimo de threads |
Propriedade do MSBuild | ThreadPoolMinThreads |
Um inteiro que representa o número mínimo de threads |
Variável de ambiente | N/D | N/D |
Exemplos
Arquivo runtimeconfig.json:
{
"runtimeOptions": {
"configProperties": {
"System.Threading.ThreadPool.MinThreads": 4
}
}
}
Arquivo runtimeconfig.template.json:
{
"configProperties": {
"System.Threading.ThreadPool.MinThreads": 4
}
}
Arquivo de projeto:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ThreadPoolMinThreads>4</ThreadPoolMinThreads>
</PropertyGroup>
</Project>
Máximo de threads
- Especifica o número máximo de threads para o pool de threads de trabalho.
- Corresponde ao método ThreadPool.SetMaxThreads.
Nome da configuração | Valores | |
---|---|---|
runtimeconfig.json | System.Threading.ThreadPool.MaxThreads |
Um inteiro que representa o número máximo de threads |
Propriedade do MSBuild | ThreadPoolMaxThreads |
Um inteiro que representa o número máximo de threads |
Variável de ambiente | N/D | N/D |
Exemplos
Arquivo runtimeconfig.json:
{
"runtimeOptions": {
"configProperties": {
"System.Threading.ThreadPool.MaxThreads": 20
}
}
}
Arquivo runtimeconfig.template.json:
{
"configProperties": {
"System.Threading.ThreadPool.MaxThreads": 20
}
}
Arquivo de projeto:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ThreadPoolMaxThreads>20</ThreadPoolMaxThreads>
</PropertyGroup>
</Project>
Pool de threads do Windows
- Para projetos no Windows, configura se o gerenciamento de threads do pool de threads é delegado ao pool de threads do Windows.
- Se você omitir essa configuração ou a plataforma não for Windows, o pool de threads do .NET será usado.
- Somente os aplicativos publicados com AOT Nativo no Windows usam o pool de threads do Windows por padrão, para o qual você pode optar por usar o pool de threads do .NET desabilitando a configuração.
- O pool de threads do Windows pode ter um desempenho melhor em alguns casos, como nos casos em que o número mínimo de threads está configurado com um valor alto ou quando o pool de threads do Windows já está sendo muito usado pelo aplicativo. Também pode haver casos em que o pool de threads do .NET tenha um desempenho melhor, como no tratamento de E/S pesada em computadores maiores. É aconselhável verificar as métricas de desempenho ao alterar essa configuração.
- Não há suporte para algumas APIs ao usar o pool de threads do Windows, como ThreadPool.SetMinThreads, ThreadPool.SetMaxThreads e ThreadPool.BindHandle(SafeHandle). As configurações do pool de threads para threads mínimos e máximos também não são eficazes. Uma alternativa para ThreadPool.BindHandle(SafeHandle) é a classe ThreadPoolBoundHandle.
Nome da configuração | Valores | Versão introduzida | |
---|---|---|---|
runtimeconfig.json | System.Threading.ThreadPool.UseWindowsThreadPool |
true - habilitadofalse -desabilitado |
.NET 8 |
Propriedade do MSBuild | UseWindowsThreadPool |
true - habilitadofalse -desabilitado |
.NET 8 |
Variável de ambiente | DOTNET_ThreadPool_UseWindowsThreadPool |
1 – Habilitado0 -desabilitado |
.NET 8 |
Exemplos
Arquivo runtimeconfig.json:
{
"runtimeOptions": {
"configProperties": {
"System.Threading.ThreadPool.UseWindowsThreadPool": true
}
}
}
Arquivo runtimeconfig.template.json:
{
"configProperties": {
"System.Threading.ThreadPool.UseWindowsThreadPool": true
}
}
Arquivo de projeto:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<UseWindowsThreadPool>true</UseWindowsThreadPool>
</PropertyGroup>
</Project>
Injeção de thread em resposta ao bloqueio de itens de trabalho
Em alguns casos, o pool de threads detecta itens de trabalho que bloqueiam seus threads. Para compensar, ele injeta mais threads. No .NET 6+, você pode usar as configurações a seguir de runtime para configurar a injeção de thread em resposta ao bloqueio de itens de trabalho. Atualmente, essas configurações têm efeito apenas para itens de trabalho que aguardam a conclusão de outra tarefa, como em casos típicos de sincronização sobre assíncrono.
Nome da configuração runtimeconfig.json | Descrição | Versão introduzida |
---|---|---|
System.Threading.ThreadPool.Blocking.ThreadsToAddWithoutDelay_ProcCountFactor |
Depois que a contagem de threads com base MinThreads é atingida, esse valor (depois de multiplicado pela contagem de processadores) especifica quantos threads adicionais podem ser criados sem atraso. |
.NET 6 |
System.Threading.ThreadPool.Blocking.ThreadsPerDelayStep_ProcCountFactor |
Depois que a contagem de threads com base em ThreadsToAddWithoutDelay é atingida, esse valor (depois de multiplicado pela contagem de processadores) especifica após quantos threads um DelayStepMs adicional seria adicionado ao atraso antes de cada novo thread ser criado. |
.NET 6 |
System.Threading.ThreadPool.Blocking.DelayStepMs |
Depois que a contagem de threads com base em ThreadsToAddWithoutDelay for atingida, esse valor especifica quanto atraso adicional adicionar por threads ThreadsPerDelayStep , que seria aplicado antes de cada novo thread ser criado. |
.NET 6 |
System.Threading.ThreadPool.Blocking.MaxDelayMs |
Depois que a contagem de threads com base em ThreadsToAddWithoutDelay for atingida, esse valor especifica o atraso máximo a ser usado antes que cada novo thread seja criado. |
.NET 6 |
System.Threading.ThreadPool.Blocking.IgnoreMemoryUsage |
Por padrão, a taxa de injeção de thread em resposta ao bloqueio é limitada pela heurística que determina se há memória física suficiente disponível. Em algumas situações, pode ser preferível injetar threads mais rapidamente, mesmo em situações de memória baixa. Você pode desabilitar a heurística de uso de memória desativando esse botão. | .NET 7 |
Como as configurações entrarão em vigor
- Depois que a contagem de threads com base em
MinThreads
for atingida, até threads adicionaisThreadsToAddWithoutDelay
poderão ser criados sem atraso. - Depois disso, antes de cada thread adicional ser criado, um atraso é induzido, começando com
DelayStepMs
. - Para cada thread
ThreadsPerDelayStep
adicionado com um atraso, umDelayStepMs
adicional é adicionado ao atraso. - O atraso não pode exceder
MaxDelayMs
. - Atrasos só são induzidos antes de criar threads. Se os threads já estiverem disponíveis, eles serão liberados sem demora para compensar o bloqueio de itens de trabalho.
- O uso e os limites de memória física também são usados e, além de um limite, o sistema muda para uma injeção de thread mais lenta.
Exemplos
Arquivo runtimeconfig.json:
{
"runtimeOptions": {
"configProperties": {
"System.Threading.ThreadPool.Blocking.ThreadsToAddWithoutDelay_ProcCountFactor": 5
}
}
}
Arquivo runtimeconfig.template.json:
{
"configProperties": {
"System.Threading.ThreadPool.Blocking.ThreadsToAddWithoutDelay_ProcCountFactor": 5
}
}
AutoreleasePool
para threads gerenciados
Essa opção configura se cada thread gerenciado recebe um NSAutoreleasePool implícito ao ser executado em uma plataforma macOS com suporte.
Nome da configuração | Valores | Versão introduzida | |
---|---|---|---|
runtimeconfig.json | System.Threading.Thread.EnableAutoreleasePool |
true ou false |
.NET 6 |
Propriedade do MSBuild | AutoreleasePoolSupport |
true ou false |
.NET 6 |
Variável de ambiente | N/D | N/D | N/D |
Exemplos
Arquivo runtimeconfig.json:
{
"runtimeOptions": {
"configProperties": {
"System.Threading.Thread.EnableAutoreleasePool": true
}
}
}
Arquivo runtimeconfig.template.json:
{
"configProperties": {
"System.Threading.Thread.EnableAutoreleasePool": true
}
}
Arquivo de projeto:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AutoreleasePoolSupport>true</AutoreleasePoolSupport>
</PropertyGroup>
</Project>