Какое максимальное количество потоков вы можете создать в приложении C #? И что происходит, когда вы достигаете этого предела? Это исключение какого-то рода?
Какое максимальное количество потоков вы можете создать в приложении C #? И что происходит, когда вы достигаете этого предела? Это исключение какого-то рода?
Ответы:
Там нет врожденного ограничения. Максимальное количество потоков определяется количеством доступных физических ресурсов. Смотрите эту статью Раймонда Чена для деталей.
Если вам нужно спросить, каково максимальное количество потоков, вы, вероятно, делаете что-то не так.
[ Обновление : Просто из интереса: .NET Thread Pool по умолчанию номера потоков:
(Эти цифры могут отличаться в зависимости от оборудования и ОС)]
Митч прав. Это зависит от ресурсов (памяти).
Хотя статья Рэймонда посвящена потокам 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, чтобы увидеть значение счетчика. Конечно, есть очень существенная разница.
Вы должны использовать пул потоков (или асинхронные delgates, которые, в свою очередь, используют пул потоков), чтобы система могла решить, сколько потоков должно выполняться.
Джефф Рихтер в CLR через C #:
«В версии 2.0 CLR максимальное число рабочих потоков по умолчанию равно 25 для каждого процессора в машине, а максимальное число потоков ввода-вывода по умолчанию равно 1000. Ограничение 1000 фактически не ограничено».
Обратите внимание, что это основано на .NET 2.0. Это могло измениться в .NET 3.5.
[Редактировать] Как заметил @Mitch, это относится к CLR ThreadPool. Если вы создаете темы, смотрите комментарии @Mitch и другие.
Вы можете проверить это, используя этот код:
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