ใน MSDN คำอธิบายของเมธอด Thread.Abort () ระบุว่า: "การเรียกใช้เมธอดนี้มักจะยุติเธรด"
ทำไมไม่อยู่เสมอ?
ในกรณีใดบ้างที่ไม่ยุติเธรด
มีความเป็นไปได้อื่น ๆ ในการยุติเธรดหรือไม่
ใน MSDN คำอธิบายของเมธอด Thread.Abort () ระบุว่า: "การเรียกใช้เมธอดนี้มักจะยุติเธรด"
ทำไมไม่อยู่เสมอ?
ในกรณีใดบ้างที่ไม่ยุติเธรด
มีความเป็นไปได้อื่น ๆ ในการยุติเธรดหรือไม่
คำตอบ:
Thread.Abort()
ฉีดThreadAbortException
บนด้าย Thread.ResetAbort()
ด้ายอาจจะยกเลิกการร้องขอโดยการเรียก นอกจากนี้ยังมีโค้ดบางส่วนเช่นfinally
บล็อกที่จะดำเนินการก่อนที่จะจัดการข้อยกเว้น หากด้วยเหตุผลบางประการเธรดติดอยู่ในบล็อกดังกล่าวข้อยกเว้นจะไม่ถูกยกขึ้นบนเธรด
เนื่องจากผู้โทรสามารถควบคุมสถานะของเธรดได้น้อยมากเมื่อโทรAbort()
โดยทั่วไปจึงไม่แนะนำให้ทำเช่นนั้น ส่งข้อความไปยังเธรดที่ขอยกเลิกแทน
ในกรณีใดบ้างที่ไม่ยุติเธรด
คำถามนี้ซ้ำกัน
เกิดอะไรขึ้นกับการใช้ Thread.Abort ()
มีความเป็นไปได้อื่น ๆ ในการยุติเธรดหรือไม่?
ใช่. ปัญหาของคุณคือคุณไม่ควรเริ่มต้นเธรดที่คุณไม่สามารถบอกอย่างสุภาพให้หยุดและมันจะหยุดในเวลาที่เหมาะสม หากคุณอยู่ในสถานการณ์ที่คุณต้องเริ่มเธรดที่อาจ (1) หยุดยาก (2) บั๊กกี้หรือเลวร้ายที่สุด (3) เป็นศัตรูกับผู้ใช้สิ่งที่ควรทำก็คือ กระบวนการใหม่เริ่มต้นเธรดในกระบวนการใหม่แล้วยุติกระบวนการเมื่อคุณต้องการให้เธรดหยุดทำงาน สิ่งเดียวที่สามารถรับประกันการยุติเธรดที่ไม่ให้ความร่วมมือได้อย่างปลอดภัยคือระบบปฏิบัติการที่จะหยุดกระบวนการทั้งหมด
ดูคำตอบที่ยาวเกินไปของฉันสำหรับคำถามนี้สำหรับรายละเอียดเพิ่มเติม:
บิตที่เกี่ยวข้องคือบิตในตอนท้ายที่ฉันพูดถึงข้อควรพิจารณาเกี่ยวกับระยะเวลาที่คุณควรรอให้เธรดฆ่าตัวตายก่อนที่คุณจะยกเลิก
ทำไมไม่อยู่เสมอ? ในกรณีใดบ้างที่จะไม่ยุติเธรด
สำหรับผู้เริ่มต้นเธรดอาจจับThreadAbortException
และยกเลิกการสิ้นสุดของตัวเอง หรืออาจทำการคำนวณที่ใช้เวลาตลอดไปในขณะที่คุณกำลังพยายามยกเลิก ด้วยเหตุนี้รันไทม์จึงไม่สามารถรับประกันได้ว่าเธรดจะจบลงหลังจากที่คุณขอไปเสมอ
ThreadAbortException
มีมากขึ้น:
เมื่อมีการเรียกใช้เมธอด Abort เพื่อทำลายเธรดรันไทม์ภาษาทั่วไปจะพ่น ThreadAbortException ThreadAbortException เป็นข้อยกเว้นพิเศษที่สามารถจับได้ แต่จะถูกเพิ่มขึ้นอีกครั้งโดยอัตโนมัติเมื่อสิ้นสุดบล็อกการจับ เมื่อเกิดข้อยกเว้นนี้รันไทม์จะเรียกใช้บล็อกสุดท้ายทั้งหมดก่อนที่จะสิ้นสุดเธรด เนื่องจากเธรดสามารถทำการคำนวณแบบไม่มีขอบเขตในบล็อกสุดท้ายหรือเรียกร้อง
Thread.ResetAbort()
ให้ยกเลิกการยกเลิกจึงไม่มีการรับประกันว่าเธรดจะสิ้นสุดลง
คุณไม่จำเป็นต้องAbort()
ร้อยด้ายด้วยตนเอง CLR จะทำงานสกปรกทั้งหมดให้คุณหากคุณปล่อยให้เมธอดในเธรดกลับมา ที่จะสิ้นสุดเธรดตามปกติ
FileStream.Read()
เพื่อไปป์ที่มีชื่อที่อยู่ในขณะนี้ไม่ได้รับอะไร (บล็อคโทรอ่านในขณะที่รอข้อมูลขาเข้า) Thread.Abort()
จะไม่ตอบสนองต่อการ มันยังคงอยู่ในการRead()
โทร
จะเกิดอะไรขึ้นถ้าเธรดกำลังล็อคและถูกยกเลิก / ถูกฆ่า? ทรัพยากรยังคงติดขัด
ทำงานได้ดีเมื่อเมื่อเธรดการเรียกยกเลิกตัวเอง แต่ไม่ใช่เธรดอื่น ยกเลิกยกเลิกเธรดที่ได้รับผลกระทบอย่างมีประสิทธิภาพแม้ว่าจะยังไม่เสร็จสิ้นภารกิจและไม่ให้โอกาสในการล้างทรัพยากร
อ้างอิงMSDN
ฉันไม่สามารถยกเลิกเธรดที่ติดอยู่ในลูปได้:
//immortal
Thread th1 = new Thread(() => { while (true) {}});
อย่างไรก็ตามฉันสามารถยกเลิกเธรดได้หากสลีประหว่างลูป:
//mortal
Thread th2 = new Thread(() => { while (true) { Thread.Sleep(1000); }});
ThreadAborts จะไม่เกิดขึ้นภายในบล็อกสุดท้ายหรือระหว่างBeginCriticalRegionและEndCriticalRegion
เนื่องจากคุณสามารถจับThreadAbortException
และโทรThread.ResetAbort
ภายในตัวจัดการได้
OT: สำหรับการใช้เวลาตลก ๆ ที่ครอบคลุมไม่เข้าใจภาษามีประโยชน์และน่าสงสัยเกี่ยวกับการเกิดพร้อมกันโปรดดูVerity Stob !
ฉันเคยมีกรณีที่เธรดยุ่งเกินกว่าที่จะได้ยินการเรียก Abort () ซึ่งมักจะส่งผลให้ ThreadAbortingException ถูกส่งไปยังรหัสของฉัน