Opcje konfiguracji środowiska uruchomieniowego na potrzeby wątkowania

W tym artykule szczegółowo przedstawiono ustawienia, których można użyć do skonfigurowania wątków na platformie .NET.

Uwaga

Program .NET 6 standardizuje prefiks DOTNET_ zamiast COMPlus_ zmiennych środowiskowych, które konfigurują zachowanie czasu wykonywania platformy .NET. COMPlus_ Jednak prefiks będzie nadal działać. Jeśli używasz poprzedniej wersji środowiska uruchomieniowego platformy .NET, nadal należy użyć prefiksu COMPlus_ dla zmiennych środowiskowych.

Używanie wszystkich grup procesora CPU w systemie Windows

  • Na maszynach, które mają wiele grup procesora CPU, to ustawienie określa, czy składniki, takie jak pula wątków, używają wszystkich grup procesora CPU, czy tylko podstawowej grupy procesora CPU procesu. To ustawienie wpływa również na to, co Environment.ProcessorCount zwraca.
  • Po włączeniu tego ustawienia używane są wszystkie grupy procesora CPU, a wątki są domyślnie automatycznie dystrybuowane między grupami procesora CPU.
  • To ustawienie jest domyślnie włączone w systemie Windows 11 i nowszych wersjach oraz jest domyślnie wyłączone w systemie Windows 10 i starszych wersjach. Aby to ustawienie miało zastosowanie po włączeniu, GC musi być również skonfigurowane do używania wszystkich grup procesora CPU; Aby uzyskać więcej informacji, zobacz Grupy procesora GC.
Nazwa ustawienia Wartości
runtimeconfig.json Brak Brak
Zmienna środowiskowa COMPlus_Thread_UseAllCpuGroups lub DOTNET_Thread_UseAllCpuGroups 0 -Wyłączone
1 -Włączone

Przypisywanie wątków do grup procesora CPU w systemie Windows

  • Na maszynach, które mają wiele grup procesora CPU i są używane wszystkie grupy procesora CPU, to ustawienie określa, czy wątki są automatycznie dystrybuowane między grupy procesora CPU.
  • Po włączeniu tego ustawienia nowe wątki są przypisywane do grupy procesora CPU w sposób, który próbuje w pełni wypełnić grupę procesora CPU, która jest już używana przed użyciem nowej grupy procesora CPU.
  • To ustawienie jest domyślnie włączone.
Nazwa ustawienia Wartości
runtimeconfig.json Brak Brak
Zmienna środowiskowa COMPlus_Thread_AssignCpuGroups lub DOTNET_Thread_AssignCpuGroups 0 -Wyłączone
1 -Włączone

Minimalna liczba wątków

Nazwa ustawienia Wartości
runtimeconfig.json System.Threading.ThreadPool.MinThreads Liczba całkowita reprezentująca minimalną liczbę wątków
Właściwość MSBuild ThreadPoolMinThreads Liczba całkowita reprezentująca minimalną liczbę wątków
Zmienna środowiskowa Brak Brak

Przykłady

Plik runtimeconfig.json :

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

plik runtimeconfig.template.json :

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

Plik projektu:

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

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

</Project>

Maksymalna liczba wątków

Nazwa ustawienia Wartości
runtimeconfig.json System.Threading.ThreadPool.MaxThreads Liczba całkowita reprezentująca maksymalną liczbę wątków
Właściwość MSBuild ThreadPoolMaxThreads Liczba całkowita reprezentująca maksymalną liczbę wątków
Zmienna środowiskowa Brak Brak

Przykłady

Plik runtimeconfig.json :

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

plik runtimeconfig.template.json :

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

Plik projektu:

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

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

</Project>

Pula wątków systemu Windows

  • W przypadku projektów w systemie Windows określa, czy zarządzanie wątkami puli wątków jest delegowane do puli wątków systemu Windows.
  • Jeśli pominięto to ustawienie lub platforma nie jest systemem Windows, zamiast tego zostanie użyta pula wątków platformy .NET.
  • Tylko aplikacje opublikowane za pomocą natywnej funkcji AOT w systemie Windows domyślnie używają puli wątków systemu Windows, dla których można wybrać opcję korzystania z puli wątków platformy .NET, wyłączając ustawienie konfiguracji.
  • Pula wątków systemu Windows może działać lepiej w niektórych przypadkach, na przykład w przypadkach, gdy minimalna liczba wątków jest skonfigurowana do wysokiej wartości lub gdy pula wątków systemu Windows jest już intensywnie używana przez aplikację. Mogą również wystąpić przypadki, w których pula wątków platformy .NET działa lepiej, na przykład w przypadku dużej liczby operacji we/wy na większych maszynach. Zaleca się sprawdzenie metryk wydajności podczas zmieniania tego ustawienia konfiguracji.
  • Niektóre interfejsy API nie są obsługiwane w przypadku korzystania z puli wątków systemu Windows, takich jak ThreadPool.SetMinThreads, ThreadPool.SetMaxThreadsi ThreadPool.BindHandle(SafeHandle). Ustawienia konfiguracji puli wątków dla minimalnych i maksymalnych wątków również nie są skuteczne. Alternatywą ThreadPool.BindHandle(SafeHandle) jest ThreadPoolBoundHandle klasa .
Nazwa ustawienia Wartości Wprowadzona wersja
runtimeconfig.json System.Threading.ThreadPool.UseWindowsThreadPool true -Włączone
false -Wyłączone
.NET 8
Właściwość MSBuild UseWindowsThreadPool true -Włączone
false -Wyłączone
.NET 8
Zmienna środowiskowa DOTNET_ThreadPool_UseWindowsThreadPool 1 -Włączone
0 -Wyłączone
.NET 8

Przykłady

Plik runtimeconfig.json :

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

plik runtimeconfig.template.json :

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

Plik projektu:

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

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

</Project>

Wstrzykiwanie wątku w odpowiedzi na blokowanie elementów roboczych

W niektórych przypadkach pula wątków wykrywa elementy robocze, które blokują jego wątki. Aby zrekompensować, wprowadza więcej wątków. W programie .NET 6+, możesz użyć następujących ustawień konfiguracji środowiska uruchomieniowego, aby skonfigurować iniekcję wątku w odpowiedzi na blokowanie elementów roboczych. Obecnie te ustawienia obowiązują tylko w przypadku elementów roboczych, które oczekują na ukończenie innego zadania, na przykład w typowych przypadkach synchronizacji za pośrednictwem asynchronicznych.

nazwa ustawienia runtimeconfig.json opis Wprowadzona wersja
System.Threading.ThreadPool.Blocking.ThreadsToAddWithoutDelay_ProcCountFactor Po osiągnięciu liczby wątków na podstawie MinThreads tej wartości (po pomnożonej przez liczbę procesorów) określa, ile dodatkowych wątków można utworzyć bez opóźnień. .NET 6
System.Threading.ThreadPool.Blocking.ThreadsPerDelayStep_ProcCountFactor Po osiągnięciu liczby wątków na podstawie ThreadsToAddWithoutDelay tej wartości (po pomnożonej przez liczbę procesorów) określa, ile wątków zostanie DelayStepMs dodanych do opóźnienia przed utworzeniem każdego nowego wątku. .NET 6
System.Threading.ThreadPool.Blocking.DelayStepMs Po osiągnięciu liczby wątków na ThreadsToAddWithoutDelay podstawie tej wartości ta wartość określa, ile dodatkowych opóźnień do dodania na ThreadsPerDelayStep wątki, które zostaną zastosowane przed utworzeniem każdego nowego wątku. .NET 6
System.Threading.ThreadPool.Blocking.MaxDelayMs Po osiągnięciu liczby wątków na ThreadsToAddWithoutDelay podstawie tej wartości ta wartość określa maksymalne opóźnienie do użycia przed utworzeniem każdego nowego wątku. .NET 6
System.Threading.ThreadPool.Blocking.IgnoreMemoryUsage Domyślnie szybkość wstrzykiwania wątku w odpowiedzi na blokowanie jest ograniczona przez heurystyki, które określają, czy jest wystarczająca ilość dostępnej pamięci fizycznej. W niektórych sytuacjach lepszym rozwiązaniem może być szybsze wstrzykiwanie wątków nawet w sytuacjach o niskiej ilości pamięci. Możesz wyłączyć heurystyki użycia pamięci, wyłączając ten przełącznik. .NET 7

Jak zaczęły obowiązywać ustawienia konfiguracji

  • Po osiągnięciu liczby wątków na MinThreads podstawie tego parametru można utworzyć maksymalnie ThreadsToAddWithoutDelay dodatkowe wątki bez opóźnień.
  • Po tym, przed utworzeniem każdego dodatkowego wątku, następuje opóźnienie, począwszy od DelayStepMs.
  • W przypadku każdego ThreadsPerDelayStep wątku, które są dodawane z opóźnieniem, do opóźnienia jest dodawany dodatkowy DelayStepMs element.
  • Opóźnienie może nie przekraczać MaxDelayMs.
  • Opóźnienia są wywoływane tylko przed utworzeniem wątków. Jeśli wątki są już dostępne, zostaną one zwolnione bez opóźnień, aby zrekompensować blokowanie elementów roboczych.
  • Używane jest również użycie pamięci fizycznej i limity, a poza progiem system przełącza się na wolniejsze wstrzykiwanie wątków.

Przykłady

Plik runtimeconfig.json :

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

plik runtimeconfig.template.json :

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

AutoreleasePool dla zarządzanych wątków

Ta opcja umożliwia skonfigurowanie, czy każdy zarządzany wątek otrzymuje niejawną pulę NSAutoreleasePool podczas uruchamiania na obsługiwanej platformie macOS.

Nazwa ustawienia Wartości Wprowadzona wersja
runtimeconfig.json System.Threading.Thread.EnableAutoreleasePool true lub false .NET 6
Właściwość MSBuild AutoreleasePoolSupport true lub false .NET 6
Zmienna środowiskowa Brak NIE DOTYCZY Brak

Przykłady

Plik runtimeconfig.json :

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

plik runtimeconfig.template.json :

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

Plik projektu:

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

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

</Project>