Opções de configuração de tempo de execução para threading
Este artigo detalha as configurações que você pode usar para configurar o threading no .NET.
Nota
O .NET 6 padroniza o prefixo DOTNET_
em vez de variáveis de ambiente que configuram o comportamento em tempo de execução do COMPlus_
.NET. No entanto, o prefixo COMPlus_
continuará a funcionar. Se você estiver usando uma versão anterior do tempo de execução do .NET, ainda deverá usar o prefixo COMPlus_
para variáveis de ambiente.
Usar todos os grupos de CPU no Windows
- Em máquinas que têm vários grupos de CPU, essa configuração define se 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 é ativada, todos os grupos de CPU são usados e os threads também são distribuídos automaticamente entre os grupos de CPU por padrão.
- Esta definição está ativada por predefinição no Windows 11 e versões posteriores e desativada por predefiniçã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 GC CPU groups.
Nome da definição | Valores | |
---|---|---|
runtimeconfig.json | N/A | N/A |
Variável de ambiente | COMPlus_Thread_UseAllCpuGroups ou DOTNET_Thread_UseAllCpuGroups |
0 - deficientes1 - ativado |
Atribuir threads a grupos de CPU no Windows
- Em máquinas 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 é habilitada, novos threads são atribuídos a um grupo de CPU de uma forma que tenta preencher totalmente um grupo de CPU que já está em uso antes de utilizar um novo grupo de CPU.
- Esta definição está ativada por predefinição.
Nome da definição | Valores | |
---|---|---|
runtimeconfig.json | N/A | N/A |
Variável de ambiente | COMPlus_Thread_AssignCpuGroups ou DOTNET_Thread_AssignCpuGroups |
0 - deficientes1 - ativado |
Mínimo de threads
- Especifica o número mínimo de threads para o pool de threads de trabalho.
- Corresponde ao ThreadPool.SetMinThreads método.
Nome da definição | Valores | |
---|---|---|
runtimeconfig.json | System.Threading.ThreadPool.MinThreads |
Um inteiro que representa o número mínimo de threads |
Propriedade MSBuild | ThreadPoolMinThreads |
Um inteiro que representa o número mínimo de threads |
Variável de ambiente | N/A | N/A |
Exemplos
Arquivo runtimeconfig.json :
{
"runtimeOptions": {
"configProperties": {
"System.Threading.ThreadPool.MinThreads": 4
}
}
}
Arquivo runtimeconfig.template.json :
{
"configProperties": {
"System.Threading.ThreadPool.MinThreads": 4
}
}
Ficheiro do projeto:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ThreadPoolMinThreads>4</ThreadPoolMinThreads>
</PropertyGroup>
</Project>
Máximo de roscas
- Especifica o número máximo de threads para o pool de threads de trabalho.
- Corresponde ao ThreadPool.SetMaxThreads método.
Nome da definição | Valores | |
---|---|---|
runtimeconfig.json | System.Threading.ThreadPool.MaxThreads |
Um inteiro que representa o número máximo de threads |
Propriedade MSBuild | ThreadPoolMaxThreads |
Um inteiro que representa o número máximo de threads |
Variável de ambiente | N/A | N/A |
Exemplos
Arquivo runtimeconfig.json :
{
"runtimeOptions": {
"configProperties": {
"System.Threading.ThreadPool.MaxThreads": 20
}
}
}
Arquivo runtimeconfig.template.json :
{
"configProperties": {
"System.Threading.ThreadPool.MaxThreads": 20
}
}
Ficheiro do 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 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 .NET em vez disso, desativando a configuração de 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 para 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 manuseio de E/S pesadas em máquinas maiores. É aconselhável verificar as métricas de desempenho ao alterar essa configuração de configuração.
- Algumas APIs não são suportadas ao usar o pool de threads do Windows, como ThreadPool.SetMinThreads, ThreadPool.SetMaxThreadse ThreadPool.BindHandle(SafeHandle). As configurações de configuração do pool de threads para threads mínimo e máximo também não são eficazes. Uma alternativa é a ThreadPool.BindHandle(SafeHandle)ThreadPoolBoundHandle classe.
Nome da definição | Valores | Versão introduzida | |
---|---|---|---|
runtimeconfig.json | System.Threading.ThreadPool.UseWindowsThreadPool |
true - ativadofalse - deficientes |
.NET 8 |
Propriedade MSBuild | UseWindowsThreadPool |
true - ativadofalse - deficientes |
.NET 8 |
Variável de ambiente | DOTNET_ThreadPool_UseWindowsThreadPool |
1 - ativado0 - deficientes |
.NET 8 |
Exemplos
Arquivo runtimeconfig.json :
{
"runtimeOptions": {
"configProperties": {
"System.Threading.ThreadPool.UseWindowsThreadPool": true
}
}
}
Arquivo runtimeconfig.template.json :
{
"configProperties": {
"System.Threading.ThreadPool.UseWindowsThreadPool": true
}
}
Ficheiro do projeto:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<UseWindowsThreadPool>true</UseWindowsThreadPool>
</PropertyGroup>
</Project>
Injeção de rosca em resposta ao bloqueio de itens de trabalho
Em alguns casos, o pool de threads deteta itens de trabalho que bloqueiam seus threads. Para compensar, injeta mais fios. No .NET 6+, você pode usar as seguintes definições de configuração de tempo de execução para configurar a injeção de thread em resposta ao bloqueio de itens de trabalho. Atualmente, essas configurações entram em vigor apenas para itens de trabalho que aguardam a conclusão de outra tarefa, como em casos típicos de sincronização sobre assíncrona .
nome da configuração runtimeconfig.json | Description | 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 do processador) 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 é ThreadsToAddWithoutDelay atingida, esse valor (depois de multiplicado pela contagem do processador) especifica quantos threads um adicional DelayStepMs seria adicionado ao atraso antes que cada novo thread seja criado. |
.NET 6 |
System.Threading.ThreadPool.Blocking.DelayStepMs |
Depois que a contagem de threads com base for ThreadsToAddWithoutDelay atingida, esse valor especifica quanto atraso adicional adicionar por ThreadsPerDelayStep threads, 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 for ThreadsToAddWithoutDelay 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 por heurísticas que determinam 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 pouca memória. Você pode desativar a heurística de uso de memória desativando essa opção. | .NET 7 |
Como as definições de configuração entram em vigor
- Depois que a contagem de threads com base em
MinThreads
for atingida, atéThreadsToAddWithoutDelay
threads adicionais podem ser criados sem atraso. - Depois disso, antes de cada thread adicional ser criado, um atraso é induzido, começando com
DelayStepMs
. - Para cada
ThreadsPerDelayStep
threads que são adicionados com um atraso, um adicionalDelayStepMs
é adicionado ao atraso. - O atraso não pode exceder
MaxDelayMs
. - Os atrasos só são induzidos antes da criação de 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
Esta opção configura se cada thread gerenciado recebe um NSAutoreleasePool implícito quando executado em uma plataforma macOS compatível.
Nome da definição | Valores | Versão introduzida | |
---|---|---|---|
runtimeconfig.json | System.Threading.Thread.EnableAutoreleasePool |
true ou false |
.NET 6 |
Propriedade MSBuild | AutoreleasePoolSupport |
true ou false |
.NET 6 |
Variável de ambiente | N/A | N/D | N/A |
Exemplos
Arquivo runtimeconfig.json :
{
"runtimeOptions": {
"configProperties": {
"System.Threading.Thread.EnableAutoreleasePool": true
}
}
}
Arquivo runtimeconfig.template.json :
{
"configProperties": {
"System.Threading.Thread.EnableAutoreleasePool": true
}
}
Ficheiro do projeto:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AutoreleasePoolSupport>true</AutoreleasePoolSupport>
</PropertyGroup>
</Project>