จำนวนเธรดสูงสุดที่คุณสามารถสร้างในแอปพลิเคชัน C # คือเท่าใด และจะเกิดอะไรขึ้นเมื่อคุณมาถึงขีด จำกัด นี้? มีการโยนข้อยกเว้นบางประเภทหรือไม่?
จำนวนเธรดสูงสุดที่คุณสามารถสร้างในแอปพลิเคชัน C # คือเท่าใด และจะเกิดอะไรขึ้นเมื่อคุณมาถึงขีด จำกัด นี้? มีการโยนข้อยกเว้นบางประเภทหรือไม่?
คำตอบ:
ไม่มีขีด จำกัด โดยธรรมชาติ จำนวนเธรดสูงสุดถูกกำหนดโดยจำนวนทรัพยากรทางกายภาพที่มีอยู่ ดูบทความนี้โดย Raymond Chenสำหรับข้อมูลเฉพาะ
หากคุณต้องการถามว่าจำนวนเธรดสูงสุดคือเท่าใดคุณอาจทำอะไรผิดพลาด
[ อัปเดต : ไม่สนใจ: .NET Thread Pool จำนวนเธรดเริ่มต้น:
(ตัวเลขเหล่านี้อาจแตกต่างกันไปขึ้นอยู่กับฮาร์ดแวร์และระบบปฏิบัติการ)]
มิทช์พูดถูก ขึ้นอยู่กับทรัพยากร (หน่วยความจำ)
แม้ว่าบทความของ Raymond จะมีไว้สำหรับเธรดของ 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 เพื่อดูค่าของตัวนับ มีความแตกต่างอย่างมีนัยสำคัญแน่นอน
ฉันทำการทดสอบบนระบบ 64 บิตพร้อมคอนโซล c # ข้อยกเว้นคือประเภทหน่วยความจำไม่เพียงพอโดยใช้เธรด 2949
ฉันรู้ว่าเราควรใช้เธรดพูลซึ่งฉันทำ แต่คำตอบนี้ตอบสนองต่อคำถามหลัก;)
คุณควรใช้เธรดพูล (หรือตัวคั่นแบบ async ซึ่งจะใช้เธรดพูล) เพื่อให้ระบบสามารถตัดสินใจได้ว่าควรรันเธรดจำนวนเท่าใด
Jeff Richter ใน CLR ผ่าน C #:
"ด้วยเวอร์ชัน 2.0 ของ CLR จำนวนเธรดผู้ปฏิบัติงานสูงสุดจะมีค่าเริ่มต้นเป็น 25 ต่อ CPU ในเครื่องและจำนวนเธรด I / O สูงสุดจะมีค่าเริ่มต้นเป็น 1,000 ขีด จำกัด 1,000 นั้นไม่มีขีด จำกัด อย่างมีประสิทธิผล"
หมายเหตุนี่ขึ้นอยู่กับ. 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