Qual é o número máximo de threads que você pode criar em um aplicativo C #? E o que acontece quando você atinge esse limite? Uma exceção de algum tipo é lançada?
Qual é o número máximo de threads que você pode criar em um aplicativo C #? E o que acontece quando você atinge esse limite? Uma exceção de algum tipo é lançada?
Respostas:
Não há limite inerente. O número máximo de encadeamentos é determinado pela quantidade de recursos físicos disponíveis. Veja este artigo de Raymond Chen para detalhes.
Se você precisar perguntar qual é o número máximo de threads, provavelmente está fazendo algo errado.
[ Atualização : Apenas por interesse: números padrão de threads do Pool de threads .NET:
(Esses números podem variar dependendo do hardware e do SO)]
Mitch está certo. Depende dos recursos (memória).
Embora o artigo de Raymond seja dedicado a threads do Windows, não a threads do C #, a lógica se aplica da mesma forma (os threads do C # são mapeados para os threads do Windows).
No entanto, como estamos em C #, se queremos ser completamente precisos, precisamos distinguir entre os segmentos "iniciado" e "não iniciado". Somente os threads iniciados realmente reservam espaço na pilha (como poderíamos esperar). Threads não iniciados alocam apenas as informações exigidas por um objeto de thread (você pode usar o refletor se estiver interessado nos membros reais).
Na verdade, você pode testá-lo, compare:
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)
{
}
}
com:
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)
{
}
}
Coloque um ponto de interrupção na exceção (sem memória, é claro) no VS para ver o valor do contador. Há uma diferença muito significativa, é claro.
Você deve usar o conjunto de encadeamentos (ou delgates assíncronos, que por sua vez usam o conjunto de encadeamentos) para que o sistema possa decidir quantos encadeamentos devem ser executados.
Jeff Richter no CLR via C #:
"Com a versão 2.0 do CLR, o número máximo de threads de trabalho padrão é 25 por CPU na máquina e o número máximo de threads de E / S é padronizado como 1000. Um limite de 1000 é efetivamente nenhum limite".
Observe que isso se baseia no .NET 2.0. Isso pode ter sido alterado no .NET 3.5.
[Editar] Como o @Mitch apontou, isso é específico do CLR ThreadPool. Se você estiver criando tópicos, consulte o @Mitch e outros comentários.
Você pode testá- lo usando este código cortado:
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);
}
}
Cuidado com o modo de aplicativo de 32 e 64 bits.
Eu recomendaria executar o método ThreadPool.GetMaxThreads na depuração
ThreadPool.GetMaxThreads(out int workerThreadsCount, out int ioThreadsCount);
Documentos e exemplos: https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool.getmaxthreads?view=netframework-4.8