Berapa jumlah maksimum utas yang dapat Anda buat dalam aplikasi C #? Dan apa yang terjadi jika Anda mencapai batas ini? Apakah pengecualian dari beberapa jenis dilemparkan?
Berapa jumlah maksimum utas yang dapat Anda buat dalam aplikasi C #? Dan apa yang terjadi jika Anda mencapai batas ini? Apakah pengecualian dari beberapa jenis dilemparkan?
Jawaban:
Tidak ada batasan yang melekat. Jumlah maksimum utas ditentukan oleh jumlah sumber daya fisik yang tersedia. Lihat artikel ini oleh Raymond Chen untuk spesifikasinya.
Jika Anda perlu bertanya berapa jumlah utas maksimum, Anda mungkin melakukan sesuatu yang salah.
[ Pembaruan : Hanya karena minat: Jumlah utas .NET Thread Pool default:
(Angka-angka ini dapat bervariasi tergantung pada perangkat keras dan OS)]
Mitch benar. Itu tergantung pada sumber daya (memori).
Meskipun artikel Raymond didedikasikan untuk utas Windows, bukan utas C #, logikanya berlaku sama (utas C # dipetakan ke utas Windows).
Namun, karena kita berada di C #, jika kita ingin benar-benar tepat, kita perlu membedakan antara utas "mulai" dan "tidak dimulai". Hanya utas awal yang benar-benar memesan ruang tumpukan (seperti yang bisa kita harapkan). Utas yang tidak dimulai hanya mengalokasikan informasi yang diperlukan oleh objek utas (Anda dapat menggunakan reflektor jika tertarik dengan anggota sebenarnya).
Anda sebenarnya bisa mengujinya sendiri, bandingkan:
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)
{
}
}
dengan:
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)
{
}
}
Letakkan breakpoint di pengecualian (kehabisan memori, tentu saja) di VS untuk melihat nilai penghitung. Ada perbedaan yang sangat signifikan tentunya.
Anda harus menggunakan kumpulan utas (atau pemisah asinkron, yang pada gilirannya menggunakan kumpulan utas) sehingga sistem dapat memutuskan berapa banyak utas yang harus dijalankan.
Jeff Richter di CLR melalui C #:
"Dengan CLR versi 2.0, jumlah maksimum utas pekerja default ke 25 per CPU di mesin dan jumlah maksimum utas I / O default ke 1000. Batas 1000 secara efektif tidak ada batasan sama sekali."
Perhatikan bahwa ini didasarkan pada .NET 2.0. Ini mungkin telah berubah di .NET 3.5.
[Sunting] Seperti yang ditunjukkan @Mitch, ini khusus untuk CLR ThreadPool. Jika Anda membuat utas secara langsung, lihat komentar @Mitch dan lainnya.
Anda dapat mengujinya dengan menggunakan kode yang dipotong ini:
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);
}
}
Waspadalah terhadap mode aplikasi 32-bit dan 64-bit.
Saya akan merekomendasikan menjalankan metode ThreadPool.GetMaxThreads di debug
ThreadPool.GetMaxThreads(out int workerThreadsCount, out int ioThreadsCount);
Docs dan contoh: https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool.getmaxthreads?view=netframework-4.8