ตรวจสอบข้อยกเว้นและกระบวนการจัดการข้อยกเว้น
- 11 นาที
ข้อผิดพลาดรันไทม์ในแอปพลิเคชัน C# ได้รับการจัดการโดยใช้กลไกที่เรียกว่า ข้อยกเว้น ข้อยกเว้นมีโครงสร้าง เหมือนกัน และชนิดที่ปลอดภัยในการจัดการทั้งระดับระบบและเงื่อนไขข้อผิดพลาดระดับแอปพลิเคชัน ข้อยกเว้นจะถูกสร้างขึ้นโดยรันไทม์ .NET หรือโดยโค้ดในแอปพลิเคชัน
สถานการณ์ทั่วไปที่จําเป็นต้องมีการจัดการข้อยกเว้น
มีสถานการณ์การเขียนโปรแกรมหลายสถานการณ์ที่จําเป็นต้องมีการจัดการข้อยกเว้น สถานการณ์เหล่านี้ส่วนใหญ่เกี่ยวข้องกับการรวบรวมข้อมูลในบางรูปแบบ แม้ว่าบางสถานการณ์เกี่ยวข้องกับเทคนิคการเขียนโค้ดที่อยู่นอกขอบเขตของการฝึกอบรมนี้ แต่ก็ยังคงคุ้มค่าที่จะสังเกต
สถานการณ์ทั่วไปที่จําเป็นต้องมีการจัดการข้อยกเว้นประกอบด้วย:
การป้อนข้อมูลของผู้ใช้: ข้อยกเว้นสามารถเกิดขึ้นได้เมื่อประมวลผลโค้ดที่ผู้ใช้ป้อนข้อมูล ตัวอย่างเช่น ข้อยกเว้นเกิดขึ้นเมื่อค่าที่ป้อนเข้าอยู่ในรูปแบบที่ไม่ถูกต้องหรืออยู่นอกช่วง
การประมวลผลข้อมูลและการคํานวณ: ข้อยกเว้นสามารถเกิดขึ้นได้เมื่อโค้ดทําการคํานวณข้อมูลหรือการแปลง ตัวอย่างเช่น ข้อยกเว้นเกิดขึ้นเมื่อพยายามหารโค้ดด้วยศูนย์ แปลงเป็นชนิดที่ไม่รองรับ หรือกําหนดค่าที่ไม่อยู่ในช่วงที่กําหนด
การดําเนินการอินพุต/เอาต์พุตของไฟล์: ข้อยกเว้นสามารถเกิดขึ้นได้เมื่ออ่านโค้ดจากหรือเขียนไปยังไฟล์ ตัวอย่างเช่น ข้อยกเว้นเกิดขึ้นเมื่อไม่มีแฟ้มนั้น อยู่ โปรแกรมไม่ได้รับอนุญาตให้เข้าถึงแฟ้ม หรือแฟ้มนั้นถูกใช้โดยกระบวนการอื่น
การดําเนินการฐานข้อมูล: ข้อยกเว้นสามารถเกิดขึ้นได้เมื่อรหัสโต้ตอบกับฐานข้อมูล ตัวอย่างเช่น ข้อยกเว้นเกิดขึ้นเมื่อการเชื่อมต่อฐานข้อมูลสูญหาย ข้อผิดพลาดทางไวยากรณ์จะเกิดขึ้นในคําสั่ง SQL หรือมีการละเมิดข้อจํากัดเกิดขึ้น
การสื่อสารเครือข่าย: ข้อยกเว้นสามารถเกิดขึ้นได้เมื่อรหัสสื่อสารบนเครือข่าย ตัวอย่างเช่น ข้อยกเว้นเกิดขึ้นเมื่อการเชื่อมต่อเครือข่ายสูญหาย การหมดเวลาเกิดขึ้น หรือเซิร์ฟเวอร์ระยะไกลส่งกลับข้อผิดพลาด
แหล่งข้อมูลภายนอกอื่น ๆ: ข้อยกเว้นสามารถเกิดขึ้นได้เมื่อรหัสสื่อสารกับทรัพยากรภายนอกอื่น ๆ Web Services, REST API หรือไลบรารีของบริษัทอื่น สามารถโยนข้อยกเว้นด้วยเหตุผลหลายประการ ตัวอย่างเช่น ข้อยกเว้นเกิดขึ้นเนื่องจากปัญหาการเชื่อมต่อเครือข่าย ข้อมูลไม่ถูกต้อง และอื่น ๆ
ข้อยกเว้นในการจัดการคําสําคัญ บล็อกโค้ด และรูปแบบ
การจัดการกับข้อยกเว้นใน C# จะถูกนํามาใช้โดยใช้tryคําสําคัญ , catchและfinally คําสําคัญแต่ละรายการเหล่านี้มีบล็อกรหัสที่เกี่ยวข้องและสามารถใช้เพื่อตอบสนองเป้าหมายที่เฉพาะเจาะจงในวิธีการของคุณเพื่อจัดการข้อยกเว้น เช่น:
try
{
// try code block - code that may generate an exception
}
catch
{
// catch code block - code to handle an exception
}
finally
{
// finally code block - code to clean up resources
}
หมายเหตุ
ภาษา C# ยังช่วยให้โค้ดของคุณสร้างอ็อปเจ็กต์ข้อยกเว้นโดยใช้คํา throw สําคัญได้ จัดการสถานการณ์ข้อยกเว้นที่รวมการใช้ throw คําสําคัญเพื่อสร้างข้อยกเว้นจะครอบคลุมในโมดูลที่แยกต่างหากบน Microsoft Learn
บล็อก try รหัสประกอบด้วยรหัสป้องกันที่อาจทําให้เกิดข้อยกเว้น ถ้ารหัสภายในtryบล็อกทําให้เกิดข้อยกเว้น ข้อยกเว้นจะถูกจัดการโดยบล็อกที่สอดคล้องกันcatch
บล็อก catch รหัสประกอบด้วยโค้ดที่ดําเนินการเมื่อจับข้อยกเว้นได้ บล็อก catch สามารถจัดการข้อยกเว้น ล็อกหรือละเว้นได้
catchบล็อกสามารถกําหนดค่าให้ทํางานเมื่อเกิดประเภทข้อยกเว้นหรือเฉพาะเมื่อเกิดข้อยกเว้นประเภทเฉพาะ
บล็อก finally รหัสประกอบด้วยโค้ดที่ดําเนินการว่ามีข้อยกเว้นเกิดขึ้นหรือไม่ บล็อก finally มักจะใช้เพื่อล้างทรัพยากรใด ๆ ที่จัดสรรใน try บล็อก ตัวอย่างเช่น การทําให้แน่ใจว่าตัวแปรมีการกําหนดค่าที่ถูกต้องหรือจําเป็น
โดยทั่วไปแล้ว การจัดการข้อยกเว้นในแอปพลิเคชัน C# จะถูกนํามาใช้โดยใช้รูปแบบต่อไปนี้อย่างน้อยหนึ่งรูปแบบ:
- รูปแบบ
try-catchประกอบด้วยtryบล็อกที่ตามด้วยส่วนคําสั่งอย่างน้อยหนึ่งcatchรายการ แต่ละcatchบล็อกถูกใช้เพื่อระบุตัวจัดการสําหรับข้อยกเว้นที่แตกต่างกัน - รูปแบบ
try-finallyประกอบด้วยtryบล็อกตามด้วยfinallyบล็อก โดยทั่วไปแล้ว คําสั่งของการfinallyเรียกใช้บล็อกเมื่อตัวควบคุมออกจากtryคําสั่ง - รูปแบบ
try-catch-finallyจะใช้บล็อกการจัดการข้อยกเว้นทั้งสามชนิด สถานการณ์ทั่วไปสําหรับtry-catch-finallyรูปแบบคือเมื่อมีการรับและใช้ทรัพยากรในtryบล็อก สถานการณ์ที่ยอดเยี่ยมจะได้รับการจัดการในcatchบล็อกและทรัพยากรจะได้รับการเผยแพร่หรือจัดการในfinallyบล็อก
ข้อยกเว้นแสดงในโค้ดอย่างไร
ข้อยกเว้นจะแสดงในโค้ดเป็นออบเจ็กต์ ซึ่งหมายความว่าเป็นอินสแตนซ์ของคลาส ไลบรารีคลาส .NET มีคลาสข้อยกเว้นที่มีการเข้าถึงในโค้ดเช่นเดียวกับคลาส .NET อื่น ๆ อีกตัวอย่างหนึ่งของคลาส .NET ที่ใช้เป็นออบเจ็กต์ในโค้ดคือ Random คลาส (ใช้เพื่อสร้างตัวเลขแบบสุ่ม)
แม่นยํายิ่งขึ้น ข้อยกเว้นคือชนิด ที่แสดงโดยคลาสที่ได้รับมาจาก System.Exceptionในท้ายที่สุด คลาสข้อยกเว้นที่มาจาก Exception การรวมข้อมูลที่ระบุชนิดของข้อยกเว้นและประกอบด้วยคุณสมบัติที่มีรายละเอียดเกี่ยวกับข้อยกเว้น การสอบรายละเอียดเพิ่มเติมของ Exception คลาสจะรวมอยู่ในโมดูลนี้ในภายหลัง
อินสแตนซ์รันไทม์ของคลาสโดยทั่วไปเรียกว่าออบเจ็กต์ ดังนั้นข้อยกเว้นมักจะเรียกว่าออบเจ็กต์ข้อยกเว้น
หมายเหตุ
แม้ว่าบางครั้งจะใช้สลับกันได้ แต่คลาสและวัตถุเป็นสิ่งที่แตกต่างกัน คลาสจะกําหนดชนิดของวัตถุ แต่ไม่ใช่วัตถุ วัตถุเป็นเอนทิตีที่เป็นรูปธรรมที่ยึดตามคลาส
จัดการกระบวนการข้อยกเว้น
เมื่อมีข้อยกเว้นเกิดขึ้น รันไทม์ .NET จะค้นหาส่วนคําสั่งที่ใกล้ที่สุด catch ที่สามารถจัดการข้อยกเว้นได้ กระบวนการเริ่มต้นด้วยเมธอด ที่ทําให้ข้อยกเว้นถูกโยน ก่อนอื่น วิธีการ จะตรวจสอบเพื่อดูว่ารหัสที่เป็นสาเหตุทําให้เกิดข้อยกเว้นอยู่ภายใน try บล็อกรหัสหรือไม่ หากรหัสอยู่ภายใน try บล็อก catch รหัส จะมีการพิจารณาส่วนคําสั่งที่เกี่ยวข้องกับ try คําสั่งตามลําดับ
catchถ้าคําสั่งไม่สามารถจัดการข้อยกเว้นได้ จะมีการค้นหาเมธอดที่เรียกเมธอดปัจจุบัน วิธีนี้จะถูกตรวจสอบเพื่อกําหนดว่าการเรียกใช้เมธอด (ไปยังวิธีแรก) อยู่ภายใน try บล็อกรหัสหรือไม่ ถ้าการโทรอยู่ภายในtryบล็อกรหัส จะมีการพิจารณาส่วนคําสั่งที่เกี่ยวข้องcatch กระบวนการค้นหานี้ดําเนินการต่อจนกว่าจะ catch พบส่วนคําสั่งที่สามารถจัดการข้อยกเว้นปัจจุบันได้
เมื่อ catch พบคําสั่งที่สามารถจัดการข้อยกเว้นได้ รันไทม์จะเตรียมการเพื่อถ่ายโอนการควบคุมไปยังคําสั่ง catch แรกของบล็อก อย่างไรก็ตาม ก่อนที่จะเริ่มการดําเนินการบล็อก catch รันไทม์จะดําเนินการบล็อกfinallyที่เกี่ยวข้องกับtryคําสั่งที่พบในระหว่างการค้นหา หากพบบล็อกมากกว่าหนึ่ง finally บล็อก บล็อกเหล่านั้นจะถูกดําเนินการโดยเริ่มต้นด้วยบล็อกที่ใกล้เคียงที่สุดกับรหัสที่ทําให้ข้อยกเว้นถูกโยน
ถ้าไม่พบ catch ส่วนคําสั่งในการจัดการข้อยกเว้น รันไทม์จะยุติแอปพลิเคชันและแสดงข้อผิดพลาดให้ผู้ใช้
พิจารณาตัวอย่างโค้ดต่อไปนี้ที่มี try-finally รูปแบบที่ซ้อนกันภายใน try-catch รูปแบบ:
try
{
// Step 1: code execution begins
try
{
// Step 2: an exception occurs here
}
finally
{
// Step 4: the system executes the finally code block associated with the try statement where the exception occurred
}
}
catch // Step 3: the system finds a catch clause that can handle the exception
{
// Step 5: the system transfers control to the first line of the catch code block
}
ในตัวอย่างนี้ กระบวนการต่อไปนี้เกิดขึ้น:
- การดําเนินการเริ่มต้นในบล็อกรหัสของคําสั่งภายนอก
try - ข้อยกเว้นจะเกิดขึ้นในบล็อกรหัสของคําสั่งภายใน
try - รันไทม์ค้นหา
catchส่วนคําสั่งที่เชื่อมโยงกับคําสั่งภายนอกtry - ก่อนที่รันไทม์จะโอนย้ายการควบคุมไปยังบรรทัด
catchแรกของบล็อกรหัส จะดําเนินการfinallyคําสั่งที่เกี่ยวข้องกับคําสั่งภายในtry - จากนั้นรันไทม์จะโอนย้ายตัวควบคุมไปยังบรรทัด
catchแรกของบล็อกรหัสและดําเนินการโค้ดที่จัดการข้อยกเว้น
ในตัวอย่างง่าย ๆ นี้ รูปแบบและtry-catchที่try-finallyซ้อนกันอยู่ภายในวิธีการเดียว แต่อาจมีการแพร่กระจายรูปแบบ และ try-catch หลายtry-finallyรูปแบบ ระหว่างวิธีการที่เรียกวิธีการอื่น
การจัดการข้อยกเว้นและสแตกการโทร
คุณมักจะเห็นคําว่า "การคลายสแตกของการโทร" เมื่อคุณอ่านเกี่ยวกับการจัดการข้อยกเว้นและกระบวนการจัดการข้อยกเว้น เพื่อทําความเข้าใจคําศัพท์นี้ คุณจําเป็นต้องทําความเข้าใจสแตกการโทรและวิธีการใช้เพื่อติดตาม "สแต็ค" ของการเรียกเมธอดระหว่างการดําเนินการโค้ด
คุณสามารถนึกภาพของกองการโทรเช่นหอคอยของบล็อก เมื่อคุณสร้างหอคอยคุณจะเริ่มต้นด้วยบล็อกเดียว แต่ละครั้งที่คุณเพิ่มบล็อกไปยังหอคอยคุณจะวางไว้ที่ด้านบนของบล็อกที่มีอยู่ เมื่อแอปพลิเคชันของคุณเริ่มต้นทํางานในโปรแกรมดีบักเกอร์ จุดเข้าใช้งานแอปพลิเคชันของคุณคือเลเยอร์แรกที่เพิ่มลงในสแต็คการโทร (บล็อกแรกของหอคอย) แต่ละครั้งที่เมธอด เรียกใช้วิธีการอื่น เมธอดใหม่จะถูกเพิ่มไปยังด้านบนของสแตก เมื่อโค้ดของคุณออกจากเมธอด เมธอด จะถูกลบออกจากสแต็คการเรียก
หมายเหตุ
สําหรับแอปพลิเคชันคอนโซล จุดเข้าใช้งานที่แอปพลิเคชันของคุณคือคําสั่งระดับบนสุด ในสแตกการเรียกรหัส Visual Studio จุดเข้าใช้งานนี้จะเรียกว่า Main เมธอด
การคลายออกสแตกคือกระบวนการที่รันไทม์ .NET ใช้เมื่อโปรแกรม C# พบข้อผิดพลาด ซึ่งเป็นกระบวนการเดียวกันกับที่คุณเพิ่งตรวจทาน
เมื่อคุณต้องลบบล็อกออกจากหอคอยคุณจะเริ่มต้นจากด้านบนและลบบล็อกแต่ละรายการจนกว่าจะถึงบล็อกที่คุณต้องการ กระบวนการนี้คล้ายกับวิธีการทํางานของการคลายสแตกซึ่งแต่ละเลเยอร์การโทรในสแต็คจะเหมือนกับบล็อกในหอคอย เมื่อรันไทม์จําเป็นต้องคลายสแตกการโทร จะเริ่มต้นจากด้านบนและลบแต่ละเลเยอร์การโทรออกจนกว่าจะถึงเลเยอร์ที่มีสิ่งที่ต้องการ ในกรณีนี้ เลเยอร์การเรียกใช้ที่ต้องการคือเมธอด ที่มี catch คําสั่งที่สามารถจัดการข้อยกเว้นที่เกิดขึ้นได้
สรุป
นี่คือสิ่งสําคัญบางอย่างที่ต้องจําจากหน่วยนี้:
- สถานการณ์ทั่วไปที่อาจจําเป็นต้องมีการจัดการข้อยกเว้นได้แก่ การป้อนข้อมูลของผู้ใช้ การประมวลผลข้อมูล การดําเนินการ I/O ของไฟล์ การดําเนินการฐานข้อมูล และการสื่อสารบนเครือข่าย
- มีการใช้งานการจัดการข้อยกเว้นใน C# โดยใช้
tryคําสําคัญ ,catchและfinallyคําสําคัญแต่ละรายการมีบล็อกโค้ดที่เกี่ยวข้องซึ่งทําหน้าที่เฉพาะเจาะจง - ข้อยกเว้นจะแสดงเป็นชนิด และได้รับมาจากคลาส ใน
System.Exception.NET ข้อยกเว้นประกอบด้วยข้อมูลที่ระบุชนิดของข้อยกเว้น และคุณสมบัติที่ให้รายละเอียดเพิ่มเติม - เมื่อมีข้อยกเว้นเกิดขึ้น รันไทม์ .NET จะค้นหาส่วนคําสั่งที่ใกล้ที่สุด
catchที่สามารถจัดการได้ การค้นหาเริ่มต้นด้วยเมธอด ที่ข้อยกเว้นถูกโยน และย้ายลงมาสแตกการเรียกถ้าจําเป็น
ตรวจสอบความรู้ของคุณ
คำติชม
หน้านี้มีประโยชน์หรือไม่
ไม่
ต้องการความช่วยเหลือในหัวข้อนี้หรือไม่
ต้องการลองใช้ Ask Learn เพื่อทําให้ชัดเจนหรือแนะนําคุณผ่านหัวข้อนี้หรือไม่