Opzioni di configurazione del runtime per il threading
Questo articolo illustra nel dettaglio le impostazioni che è possibile usare per configurare il threading in .NET.
Nota
.NET 6 standardizza il prefisso DOTNET_
anziché COMPlus_
per le variabili di ambiente che configurano il comportamento di runtime di .NET. Tuttavia, il prefisso COMPlus_
continuerà a funzionare. Se si usa una versione precedente del runtime .NET, è comunque consigliabile usare il prefisso COMPlus_
per le variabili di ambiente.
Usare tutti i gruppi di CPU in Windows
- Nei computer con più gruppi di CPU questa impostazione consente di determinare 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 sul valore restituito da Environment.ProcessorCount.
- Quando questa impostazione è abilitata, vengono usati tutti i gruppi di CPU e i thread vengono anche distribuiti automaticamente 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 Garbage Collection per l'uso di tutti i gruppi di CPU; Per altre informazioni, vedere Gruppi di CPU per Garbage Collection.
Nome impostazione | Valori | |
---|---|---|
runtimeconfig.json | N/D | N/D |
Variabile di ambiente | COMPlus_Thread_UseAllCpuGroups oppure DOTNET_Thread_UseAllCpuGroups |
0 - disabilitata1 - abilitata |
Assegnare thread a gruppi di CPU in Windows
- Nei computer con più gruppi di CPU e in cui 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 provare a popolare completamente un gruppo di CPU già in uso prima di utilizzare un nuovo gruppo di CPU.
- Questa opzione è attivata per impostazione predefinita.
Nome impostazione | Valori | |
---|---|---|
runtimeconfig.json | N/D | N/D |
Variabile di ambiente | COMPlus_Thread_AssignCpuGroups oppure DOTNET_Thread_AssignCpuGroups |
0 - disabilitata1 - abilitata |
Numero minimo di thread
- Specifica il numero minimo di thread per il pool di thread di lavoro.
- Corrisponde al metodo ThreadPool.SetMinThreads.
Nome impostazione | Valori | |
---|---|---|
runtimeconfig.json | System.Threading.ThreadPool.MinThreads |
Numero intero che rappresenta il numero minimo di thread |
Proprietà MSBuild | ThreadPoolMinThreads |
Numero intero che rappresenta il numero minimo di thread |
Variabile di ambiente | N/D | N/D |
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 metodo ThreadPool.SetMaxThreads.
Nome impostazione | Valori | |
---|---|---|
runtimeconfig.json | System.Threading.ThreadPool.MaxThreads |
Numero intero che rappresenta il numero massimo di thread |
Proprietà MSBuild | ThreadPoolMaxThreads |
Numero intero che rappresenta il numero massimo di thread |
Variabile di ambiente | N/D | N/D |
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, determina 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 su un valore elevato o quando il pool di thread di Windows è già usato in modo significativo dall'app. Possono anche verificarsi casi in cui il pool di thread .NET offre prestazioni migliori, ad esempio nella gestione di operazioni a uso elevato di I/O 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.SetMaxThreads e ThreadPool.BindHandle(SafeHandle). Anche le impostazioni di configurazione del pool di thread per il numero minimo e massimo di thread non sono valide. Un'alternativa a ThreadPool.BindHandle(SafeHandle) è la classe ThreadPoolBoundHandle.
Nome impostazione | Valori | Versione introdotta | |
---|---|---|---|
runtimeconfig.json | System.Threading.ThreadPool.UseWindowsThreadPool |
true - abilitatafalse - disabilitata |
.NET 8 |
Proprietà MSBuild | UseWindowsThreadPool |
true : abilitatafalse - disabilitata |
.NET 8 |
Variabile di ambiente | DOTNET_ThreadPool_UseWindowsThreadPool |
1 - abilitata0 - 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 a elementi di lavoro bloccanti
In alcuni casi il pool di thread rileva elementi di lavoro che bloccano i thread. Per compensare, inserisce più thread. In .NET 6+ è possibile usare le impostazioni di configurazione del runtime seguenti per configurare l'inserimento di thread in risposta a elementi di lavoro bloccanti. Queste impostazioni vengono attualmente applicate solo per gli elementi di lavoro che attendono il completamento di un'altra attività, ad esempio nei casi sincrono su asincrono.
Nome dell'impostazione di runtimeconfig.json | Descrizione | Versione introdotta |
---|---|---|
System.Threading.ThreadPool.Blocking.ThreadsToAddWithoutDelay_ProcCountFactor |
Dopo il raggiungimento del numero di thread basato su MinThreads , questo valore (dopo che viene moltiplicato per il numero di processori) specifica il numero di thread aggiuntivi che possono essere creati senza ritardi. |
.NET 6 |
System.Threading.ThreadPool.Blocking.ThreadsPerDelayStep_ProcCountFactor |
Dopo il raggiungimento del numero di thread basato su ThreadsToAddWithoutDelay , questo valore (dopo che viene moltiplicato per il numero di processori) specifica il numero di thread dopo cui altri DelayStepMs verrebbero aggiunti al ritardo prima della creazione di ogni nuovo thread. |
.NET 6 |
System.Threading.ThreadPool.Blocking.DelayStepMs |
Dopo il raggiungimento del numero di thread basato su ThreadsToAddWithoutDelay , questo valore specifica il ritardo aggiuntivo da aggiungere per ogni thread ThreadsPerDelayStep , che verrebbe applicato prima della creazione di ogni nuovo thread. |
.NET 6 |
System.Threading.ThreadPool.Blocking.MaxDelayMs |
Dopo il raggiungimento del numero di thread basato su ThreadsToAddWithoutDelay , 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 |
Modalità di applicazione delle impostazioni di configurazione
- Dopo il raggiungimento del numero di thread basato su
MinThreads
, è possibile creare fino aThreadsToAddWithoutDelay
thread aggiuntivi senza alcun ritardo. - Successivamente, prima di creare ogni thread aggiuntivo, viene indotto un ritardo, a partire da
DelayStepMs
. - Per ogni thread
ThreadsPerDelayStep
aggiunto con un ritardo,DelayStepMs
aggiuntivi vengono aggiunti al ritardo. - Il ritardo non può superare il valore di
MaxDelayMs
. - I ritardi vengono indotti solo prima di creare thread. Se i thread sono già disponibili, verranno rilasciati senza ritardo per compensare per gli elementi di lavoro bloccanti.
- Vengono usati anche i limiti e l'utilizzo della memoria fisica e, oltre una soglia, il sistema passa a un inserimento più lento di thread.
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 thread gestiti
Questa opzione consente di configurare se ogni thread gestito riceve un implicito NSAutoreleasePool durante l'esecuzione in una piattaforma macOS supportata.
Nome impostazione | Valori | Versione introdotta | |
---|---|---|---|
runtimeconfig.json | System.Threading.Thread.EnableAutoreleasePool |
true oppure false |
.NET 6 |
Proprietà MSBuild | AutoreleasePoolSupport |
true oppure false |
.NET 6 |
Variabile di ambiente | N/D | N/D | N/D |
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>