Максимальное количество потоков в приложении .NET?

Какое максимальное количество потоков вы можете создать в приложении C#? А что произойдет, когда вы достигнете этого предела? Выбрасывается ли какое-то исключение?

Ответ будет отличаться, если вы используете виртуальную машину x64 или виртуальную машину x86.

Brian R. Bondy 28.09.2008 10:07

В моей ситуации это x86, но можете ли вы дать ответ на оба вопроса, если это понадобится кому-то другому?

creedence.myopenid.com 28.09.2008 10:10
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
146
2
145 789
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Ответ принят как подходящий

Нет внутреннего предела. Максимальное количество потоков определяется количеством доступных физических ресурсов. См. Этот статья Раймонда Чена для подробностей.

Если вам нужно спросить, каково максимальное количество потоков, вероятно, вы что-то делаете не так.

[Обновлять: Просто из интереса: количество потоков по умолчанию в пуле потоков .NET:

  • 1023 в Framework 4.0 (32-разрядная среда)
  • 32767 в Framework 4.0 (64-битная среда)
  • 250 на ядро ​​в Framework 3.5
  • 25 на ядро ​​в Framework 2.0

(Эти числа могут отличаться в зависимости от оборудования и ОС)]

Как ты это понял? Вы знаете, что такое .NET 4.5 или какой будет 5.0?

halfbit 21.10.2012 17:31

Вы можете использовать этот код для получения подсчетов: int workerThreads; int CompletionPortThreads; ThreadPool.GetMaxThreads (из workerThreads, из завершенияPortThreads);

JALLRED 09.06.2014 21:03

@MitchWheat - краткое изложение ссылки было бы здорово, в случае, если страница больше не доступна.

pqsk 22.12.2014 23:26

@pqsk: а как вы думаете, что это за маркированный список?

Mitch Wheat 23.12.2014 01:55

@MitchWheat Мне самому было интересно, потому что в связанной статье обсуждается не .NET, а простой C.

pqsk 23.12.2014 04:47

Это поддерживает Джо Альбахари. albahari.com/threading/#_Optimizing_the_Thread_Pool

Andy James 20.11.2017 01:57

@MitchWheat Это касается рабочих потоков, как выполняется определение для потоков ввода-вывода (PortCompletion)

johnny 5 24.01.2018 01:30

@johnny: этому вопросу 9 лет: я предлагаю вам задать новый конкретный вопрос.

Mitch Wheat 24.01.2018 02:27

Просто из любопытства, что происходит, когда ваше приложение достигает максимально возможного количества потоков? Он перестает отвечать и просто закрывается сам по себе ?? Если это приложение формы Windows C#, отображается ли форма неактивной и закрывается после ??

LoukMouk 01.08.2018 15:00

@LoukMo: если вы не можете создать поток, возможно, у вас закончилась память! Я не пробовал, но предполагаю, что будет выброшено исключение памяти ....?

Mitch Wheat 01.08.2018 15:29

@MitchWheat в Framework 4.0 и выше в 64-битной среде - это 32767, а не 32768. Вы можете легко проверить это, используя этот код: ThreadPool.GetMaxThreads(out var maxWorkerThreads, out var maxCompletionPortThreads);, где значение maxWorkerThreads - это значение, которое мы ищем.

B.Kosmowski 09.10.2018 23:00

@ B.Kosmowski: ThreadPool.GetMaxThreads () "Извлекает количество запросов к пулу потоков, которые могут быть активными одновременно"

Mitch Wheat 10.10.2018 03:45

@MitchWheat А почему вы написали 32768 вместо 32767?

B.Kosmowski 11.10.2018 10:21

@Liam Теперь ссылка должна быть исправлена.

Eugene Komisarenko 15.08.2019 18:07

Джефф Рихтер в CLR через C#:

"В среде CLR версии 2.0 максимальное количество рабочих потоков по умолчанию 25 на процессор в машине и максимальное количество входов / выходов по умолчанию количество потоков равно 1000. Предел в 1000 фактически не является пределом ".

Обратите внимание, что это основано на .NET 2.0. Это могло измениться в .NET 3.5.

[Edit] Как заметил @Mitch, это специфично для CLR ThreadPool. Если вы создаете темы, смотрите комментарии @Mitch и других.

Вы путаете CLR 2.0 и .NET 2.0 в своем комментарии о .NET 3.5.

bzlm 01.10.2008 16:01

Насколько мне известно, SP1 для .NET 2.0 (часть .NET 3.5) изменил количество рабочих потоков по умолчанию на 250 на процессор / ядро ​​для пулов потоков.

Michael Damatov 02.10.2008 23:46

Митч прав. Это зависит от ресурсов (памяти).

Хотя статья Раймонда посвящена потокам Windows, а не потокам C#, логика применима так же (потоки C# отображаются на потоки Windows).

Однако, поскольку мы находимся в C#, если мы хотим быть полностью точными, нам нужно различать «запущенные» и «не запущенные» потоки. Только запущенные потоки фактически резервируют пространство стека (как и следовало ожидать). Не запущенные потоки выделяют только ту информацию, которая требуется объекту потока (вы можете использовать отражатель, если заинтересованы в фактических членах).

Вы действительно можете проверить это на себе, сравните:

    static void DummyCall()
    {
        Thread.Sleep(1000000000);
    }

    static void Main(string[] args)
    {
        int count = 0;
        var threadList = new List<Thread>();
        try
        {
            while (true)
            {
                Thread newThread = new Thread(new ThreadStart(DummyCall), 1024);
                newThread.Start();
                threadList.Add(newThread);
                count++;
            }
        }
        catch (Exception ex)
        {
        }
    }

с:

   static void DummyCall()
    {
        Thread.Sleep(1000000000);
    }

    static void Main(string[] args)
    {
        int count = 0;
        var threadList = new List<Thread>();
        try
        {
            while (true)
            {
                Thread newThread = new Thread(new ThreadStart(DummyCall), 1024);
                threadList.Add(newThread);
                count++;
            }
        }
        catch (Exception ex)
        {
        }
    }

Поместите точку останова в исключение (конечно, из-за нехватки памяти) в VS, чтобы увидеть значение счетчика. Конечно, есть очень существенная разница.

Вы должны использовать пул потоков (или асинхронные делегаты, которые, в свою очередь, используют пул потоков), чтобы система могла решить, сколько потоков должно выполняться.

Ответ является, чтобы позволить системе решить.

Ian Boyd 08.07.2009 01:32

@Ian: Я отрицательно проголосовал за вас, потому что такой же ответ был дан девять месяцев назад.

John Saunders 09.09.2009 10:13

Связь. Я не вижу упоминания о пуле потоков в качестве чьего-либо ответа.

Ian Boyd 10.09.2009 00:14

Я провел тест на 64-битной системе с консолью C#, исключение - тип нехватки памяти с использованием 2949 потоков.

Я понимаю, что мы должны использовать пул потоков, что я и делаю, но этот ответ является ответом на основной вопрос;)

Вы можете тестовое задание использовать этот фрагмент кода:

private static void Main(string[] args)
{
   int threadCount = 0;
   try
   {
      for (int i = 0; i < int.MaxValue; i ++)
      {
         new Thread(() => Thread.Sleep(Timeout.Infinite)).Start();
         threadCount ++;
      }
   }
   catch
   {
      Console.WriteLine(threadCount);
      Console.ReadKey(true);
   }
}

Остерегайтесь 32-битного и 64-битного режима приложения.

Я бы рекомендовал запустить метод ThreadPool.GetMaxThreads в отладке

ThreadPool.GetMaxThreads(out int workerThreadsCount, out int ioThreadsCount);

Документы и примеры: https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool.getmaxthreads?view=netframework-4.8

Другие вопросы по теме