Partilhar via


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 - deficientes
1 - 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 - deficientes
1 - 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 - ativado
false - deficientes
.NET 8
Propriedade MSBuild UseWindowsThreadPool true - ativado
false - deficientes
.NET 8
Variável de ambiente DOTNET_ThreadPool_UseWindowsThreadPool 1 - ativado
0 - 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 adicional DelayStepMs é 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>