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

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

Ответ 1

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

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

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

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

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

Ответ 2

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

Хотя статья Raymond посвящена потокам Windows, а не потокам С#, логика применяет то же самое (потоки С# сопоставляются с потоками Windows).

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

Вы можете проверить его сами, сравните:

    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, чтобы увидеть значение счетчика. Разумеется, существует очень значительная разница.

Ответ 3

Я сделал тест на 64-битной системе с консолью С#, исключение - это тип из памяти, используя потоки 2949.

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

Ответ 4

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

Ответ 5

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

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

Примечание. Это основано на .NET 2.0. Возможно, это изменилось в .NET 3.5.

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