Condividi tramite


Opzioni di configurazione del runtime per il threading

Questo articolo illustra in dettaglio le impostazioni che è possibile usare per configurare il threading in .NET.

Usare tutti i gruppi di CPU in Windows

  • Nei computer con più gruppi di CPU questa impostazione consente di configurare se i componenti, ad esempio il pool di thread, usano tutti i gruppi di CPU o solo il gruppo di CPU primario del processo. L'impostazione influisce anche sui risultati Environment.ProcessorCount restituiti.
  • Quando questa impostazione è abilitata, vengono usati tutti i gruppi di CPU e i thread vengono distribuiti automaticamente anche tra i gruppi di CPU per impostazione predefinita.
  • Questa impostazione è abilitata per impostazione predefinita in Windows 11 e versioni successive e disabilitata per impostazione predefinita in Windows 10 e versioni precedenti. Affinché questa impostazione venga applicata quando abilitata, è necessario configurare anche GC per l'uso di tutti i gruppi di CPU; per altre informazioni, vedere Gruppi di CPU GC.
Nome della impostazione Valori
runtimeconfig.json N/A N/A
Variabile di ambiente DOTNET_Thread_UseAllCpuGroups 0 - disabilitata
1 - abilitato

Assegnare thread a gruppi di CPU in Windows

  • Nei computer con più gruppi di CPU e vengono usati tutti i gruppi di CPU, questa impostazione consente di configurare se i thread vengono distribuiti automaticamente tra gruppi di CPU.
  • Quando questa impostazione è abilitata, i nuovi thread vengono assegnati a un gruppo di CPU in modo da cercare di popolare completamente un gruppo di CPU già in uso prima di usare un nuovo gruppo di CPU.
  • Questa opzione è attivata per impostazione predefinita.
Nome della impostazione Valori
runtimeconfig.json N/A N/A
Variabile di ambiente DOTNET_Thread_AssignCpuGroups 0 - disabilitata
1 - abilitato

Thread minimi

  • Specifica il numero minimo di thread per il pool di thread di lavoro.
  • Corrisponde al ThreadPool.SetMinThreads metodo .
Nome della impostazione Valori
runtimeconfig.json System.Threading.ThreadPool.MinThreads Intero che rappresenta il numero minimo di thread
Proprietà MSBuild ThreadPoolMinThreads Intero che rappresenta il numero minimo di thread
Variabile di ambiente N/A N/A

Esempi

File runtimeconfig.json:

{
   "runtimeOptions": {
      "configProperties": {
         "System.Threading.ThreadPool.MinThreads": 4
      }
   }
}

File runtimeconfig.template.json:

{
   "configProperties": {
      "System.Threading.ThreadPool.MinThreads": 4
   }
}

File di progetto:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <ThreadPoolMinThreads>4</ThreadPoolMinThreads>
  </PropertyGroup>

</Project>

Numero massimo di thread

  • Specifica il numero massimo di thread per il pool di thread di lavoro.
  • Corrisponde al ThreadPool.SetMaxThreads metodo .
Nome della impostazione Valori
runtimeconfig.json System.Threading.ThreadPool.MaxThreads Intero che rappresenta il numero massimo di thread
Proprietà MSBuild ThreadPoolMaxThreads Intero che rappresenta il numero massimo di thread
Variabile di ambiente N/A N/A

Esempi

File runtimeconfig.json:

{
   "runtimeOptions": {
      "configProperties": {
         "System.Threading.ThreadPool.MaxThreads": 20
      }
   }
}

File runtimeconfig.template.json:

{
   "configProperties": {
      "System.Threading.ThreadPool.MaxThreads": 20
   }
}

File di progetto:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <ThreadPoolMaxThreads>20</ThreadPoolMaxThreads>
  </PropertyGroup>

</Project>

Pool di thread di Windows

  • Per i progetti in Windows, configura se la gestione dei thread del pool di thread è delegata al pool di thread di Windows.
  • Se si omette questa impostazione o la piattaforma non è Windows, viene invece usato il pool di thread .NET.
  • Solo le applicazioni pubblicate con AOT nativo in Windows usano il pool di thread di Windows per impostazione predefinita, per cui è possibile scegliere di usare il pool di thread .NET disabilitando invece l'impostazione di configurazione.
  • Il pool di thread di Windows può offrire prestazioni migliori in alcuni casi, ad esempio nei casi in cui il numero minimo di thread è configurato per un valore elevato o quando il pool di thread di Windows è già usato pesantemente dall'app. Possono anche verificarsi casi in cui il pool di thread .NET offre prestazioni migliori, ad esempio nella gestione di operazioni di I/O pesanti su computer di dimensioni maggiori. È consigliabile controllare le metriche delle prestazioni quando si modifica questa impostazione di configurazione.
  • Alcune API non sono supportate quando si usa il pool di thread di Windows, ad esempio ThreadPool.SetMinThreads, ThreadPool.SetMaxThreadse ThreadPool.BindHandle(SafeHandle). Anche le impostazioni di configurazione del pool di thread per thread minimi e massimi non sono valide. Un'alternativa a ThreadPool.BindHandle(SafeHandle) è la ThreadPoolBoundHandle classe .
Nome della impostazione Valori Versione introdotta
runtimeconfig.json System.Threading.ThreadPool.UseWindowsThreadPool true - abilitato
false - disabilitata
.NET 8
Proprietà MSBuild UseWindowsThreadPool true - abilitato
false - disabilitata
.NET 8
Variabile di ambiente DOTNET_ThreadPool_UseWindowsThreadPool 1 - abilitato
0 - disabilitata
.NET 8

Esempi

File runtimeconfig.json:

{
   "runtimeOptions": {
      "configProperties": {
         "System.Threading.ThreadPool.UseWindowsThreadPool": true
      }
   }
}

File runtimeconfig.template.json:

{
   "configProperties": {
      "System.Threading.ThreadPool.UseWindowsThreadPool": true
   }
}

File di progetto:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <UseWindowsThreadPool>true</UseWindowsThreadPool>
  </PropertyGroup>

</Project>

Inserimento di thread in risposta al blocco degli elementi di lavoro

In alcuni casi, il pool di thread rileva gli elementi di lavoro che bloccano i thread. Per compensare, inserisce più thread. In .NET 6+, è possibile usare le impostazioni di configurazione di runtime seguenti per configurare l'inserimento di thread in risposta al blocco degli elementi di lavoro. Attualmente, queste impostazioni diventano effettive solo per gli elementi di lavoro che attendono il completamento di un'altra attività, ad esempio nei casi tipici di sincronizzazione su asincrona .

runtimeconfig.jsonnome dell'impostazione Description Versione introdotta
System.Threading.ThreadPool.Blocking.ThreadsToAddWithoutDelay_ProcCountFactor Dopo aver raggiunto il numero di thread in MinThreads base al raggiungimento, questo valore (dopo che viene moltiplicato per il numero di processori) specifica il numero di thread aggiuntivi che possono essere creati senza alcun ritardo. .NET 6
System.Threading.ThreadPool.Blocking.ThreadsPerDelayStep_ProcCountFactor Dopo che il numero di thread in ThreadsToAddWithoutDelay base a viene raggiunto, questo valore (dopo che viene moltiplicato per il numero di processori) specifica dopo il numero di thread che verranno aggiunti un ulteriore DelayStepMs thread al ritardo prima della creazione di ogni nuovo thread. .NET 6
System.Threading.ThreadPool.Blocking.DelayStepMs Dopo aver raggiunto il numero di thread in ThreadsToAddWithoutDelay base a , questo valore specifica il ritardo aggiuntivo da aggiungere per ThreadsPerDelayStep ogni thread, che verrebbe applicato prima della creazione di ogni nuovo thread. .NET 6
System.Threading.ThreadPool.Blocking.MaxDelayMs Dopo aver raggiunto il numero di thread in ThreadsToAddWithoutDelay base a , questo valore specifica il ritardo massimo da usare prima della creazione di ogni nuovo thread. .NET 6
System.Threading.ThreadPool.Blocking.IgnoreMemoryUsage Per impostazione predefinita, la frequenza di inserimento di thread in risposta al blocco è limitata dall'euristica che determina se è disponibile memoria fisica sufficiente. In alcune situazioni, può essere preferibile inserire thread più rapidamente anche in situazioni di memoria insufficiente. È possibile disabilitare l'euristica dell'utilizzo della memoria disattivando questa opzione. .NET 7

Effetto delle impostazioni di configurazione

  • Dopo aver raggiunto il numero di thread in MinThreads base a , è possibile creare fino a ThreadsToAddWithoutDelay thread aggiuntivi senza alcun ritardo.
  • Successivamente, prima di creare ogni thread aggiuntivo, viene indotto un ritardo, a partire da DelayStepMs.
  • Per ogni ThreadsPerDelayStep thread aggiunto con un ritardo, viene aggiunto un ulteriore DelayStepMs al ritardo.
  • Il ritardo potrebbe non superare MaxDelayMs.
  • I ritardi vengono indotti solo prima di creare thread. Se i thread sono già disponibili, verranno rilasciati senza ritardo per compensare il blocco degli elementi di lavoro.
  • Vengono usati anche i limiti e l'utilizzo della memoria fisica e, oltre una soglia, il sistema passa all'inserimento di thread più lento.

Esempi

File runtimeconfig.json:

{
   "runtimeOptions": {
      "configProperties": {
         "System.Threading.ThreadPool.Blocking.ThreadsToAddWithoutDelay_ProcCountFactor": 5
      }
   }
}

File runtimeconfig.template.json:

{
   "configProperties": {
      "System.Threading.ThreadPool.Blocking.ThreadsToAddWithoutDelay_ProcCountFactor": 5
   }
}

AutoreleasePool per i thread gestiti

Questa opzione consente di configurare se ogni thread gestito riceve un NSAutoreleasePool implicito durante l'esecuzione in una piattaforma macOS supportata.

Nome della impostazione Valori Versione introdotta
runtimeconfig.json System.Threading.Thread.EnableAutoreleasePool true o false .NET 6
Proprietà MSBuild AutoreleasePoolSupport true o false .NET 6
Variabile di ambiente N/A N/A N/A

Esempi

File runtimeconfig.json:

{
   "runtimeOptions": {
      "configProperties": {
         "System.Threading.Thread.EnableAutoreleasePool": true
      }
   }
}

File runtimeconfig.template.json:

{
   "configProperties": {
      "System.Threading.Thread.EnableAutoreleasePool": true
   }
}

File di progetto:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <AutoreleasePoolSupport>true</AutoreleasePoolSupport>
  </PropertyGroup>

</Project>