WPF - การจัดการข้อยกเว้น
ข้อยกเว้นคือเงื่อนไขข้อผิดพลาดหรือลักษณะการทำงานที่ไม่คาดคิดที่พบระหว่างการทำงานของโปรแกรม ข้อยกเว้นสามารถยกขึ้นได้เนื่องจากหลายสาเหตุบางส่วนมีดังนี้ -
ความผิดพลาดในรหัสของคุณหรือในรหัสที่คุณเรียก (เช่นไลบรารีที่ใช้ร่วมกัน)
ทรัพยากรระบบปฏิบัติการไม่พร้อมใช้งาน
เงื่อนไขที่ไม่คาดคิดที่รันไทม์ภาษาทั่วไปพบ (เช่นรหัสที่ไม่สามารถตรวจสอบได้)
ไวยากรณ์
ข้อยกเว้นมีความสามารถในการถ่ายโอนโฟลว์ของโปรแกรมจากส่วนหนึ่งไปยังอีกส่วนหนึ่ง ใน. NET Framework การจัดการข้อยกเว้นมีคำหลักสี่คำต่อไปนี้ -
try - ในบล็อกนี้โปรแกรมจะระบุเงื่อนไขบางประการซึ่งทำให้เกิดข้อยกเว้นบางประการ
catch- คีย์เวิร์ดที่จับได้บ่งบอกถึงการจับข้อยกเว้น กtry ตามด้วยอย่างน้อยหนึ่งบล็อก catch บล็อกเพื่อตรวจจับข้อยกเว้นด้วยตัวจัดการข้อยกเว้นที่ตำแหน่งในโปรแกรมที่คุณต้องการจัดการปัญหา
finally- บล็อกสุดท้ายใช้เพื่อดำเนินการชุดคำสั่งที่กำหนดไม่ว่าจะมีการโยนข้อยกเว้นหรือไม่ก็ตาม ตัวอย่างเช่นหากคุณเปิดไฟล์ไฟล์นั้นจะต้องปิดไม่ว่าจะมีการเพิ่มข้อยกเว้นหรือไม่ก็ตาม
throw- โปรแกรมจะแสดงข้อยกเว้นเมื่อปัญหาปรากฏขึ้น สิ่งนี้ทำได้โดยใช้คีย์เวิร์ด Throw
ไวยากรณ์ที่จะใช้คำหลักทั้งสี่นี้มีดังนี้ -
try {
///This will still trigger the exception
}
catch (ExceptionClassName e) {
// error handling code
}
catch (ExceptionClassName e) {
// error handling code
}
catch (ExceptionClassName e) {
// error handling code
}
finally {
// statements to be executed
}
คำสั่ง catch หลายคำถูกใช้ในกรณีที่ try block สามารถเพิ่มข้อยกเว้นได้มากกว่าหนึ่งข้อขึ้นอยู่กับสถานการณ์ของโฟลว์โปรแกรม
ลำดับชั้น
คลาสข้อยกเว้นเกือบทั้งหมดใน. NET framework ได้มาจากคลาส Exception โดยตรงหรือโดยอ้อม คลาสข้อยกเว้นที่สำคัญที่สุดที่ได้รับจากคลาส Exception คือ -
ApplicationException class- รองรับข้อยกเว้นที่สร้างขึ้นโดยโปรแกรม เมื่อผู้พัฒนาต้องการกำหนดข้อยกเว้นคลาสควรได้รับจากคลาสนี้
SystemException class- เป็นคลาสพื้นฐานสำหรับข้อยกเว้นของระบบรันไทม์ที่กำหนดไว้ล่วงหน้าทั้งหมด ลำดับชั้นต่อไปนี้แสดงข้อยกเว้นมาตรฐานที่จัดเตรียมโดยรันไทม์
ตารางต่อไปนี้แสดงรายการข้อยกเว้นมาตรฐานที่จัดเตรียมโดยรันไทม์และเงื่อนไขที่คุณควรสร้างคลาสที่ได้รับ
ประเภทข้อยกเว้น | ประเภทฐาน | คำอธิบาย |
---|---|---|
Exception | วัตถุ | คลาสพื้นฐานสำหรับข้อยกเว้นทั้งหมด |
SystemException | ข้อยกเว้น | คลาสพื้นฐานสำหรับข้อผิดพลาดที่สร้างโดยรันไทม์ทั้งหมด |
IndexOutOfRangeException | SystemException | โยนโดยรันไทม์เฉพาะเมื่ออาร์เรย์ถูกจัดทำดัชนีไม่ถูกต้อง |
NullReferenceException | SystemException | โยนโดยรันไทม์เฉพาะเมื่อมีการอ้างอิงอ็อบเจ็กต์ null |
AccessViolationException | SystemException | โยนโดยรันไทม์เมื่อเข้าถึงหน่วยความจำไม่ถูกต้องเท่านั้น |
InvalidOperationException | SystemException | โยนโดยวิธีการเมื่ออยู่ในสถานะที่ไม่ถูกต้อง |
ArgumentException | SystemException | คลาสฐานสำหรับข้อยกเว้นอาร์กิวเมนต์ทั้งหมด |
ArgumentNullException | ArgumentException | โยนโดยวิธีการที่ไม่อนุญาตให้อาร์กิวเมนต์เป็นโมฆะ |
ArgumentOutOfRangeException | ArgumentException | โยนโดยวิธีการที่ตรวจสอบว่าอาร์กิวเมนต์อยู่ในช่วงที่กำหนด |
ExternalException | SystemException | คลาสพื้นฐานสำหรับข้อยกเว้นที่เกิดขึ้นหรือถูกกำหนดเป้าหมายไว้ที่สภาพแวดล้อมนอกรันไทม์ |
SEHException | ExternalException | ข้อยกเว้นการห่อหุ้มข้อมูลการจัดการข้อยกเว้นที่มีโครงสร้าง Win32 |
ตัวอย่าง
ลองมาเป็นตัวอย่างง่ายๆเพื่อทำความเข้าใจแนวคิดกันดีกว่า เริ่มต้นด้วยการสร้างโครงการ WPF ใหม่ด้วยชื่อWPFExceptionHandling.
ลากกล่องข้อความหนึ่งกล่องจากกล่องเครื่องมือไปที่หน้าต่างออกแบบ รหัส XAML ต่อไปนี้สร้างกล่องข้อความและเริ่มต้นด้วยคุณสมบัติบางอย่าง
<Window x:Class = "WPFExceptionHandling.MainWindow"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local = "clr-namespace:WPFExceptionHandling"
mc:Ignorable = "d"
Title = "MainWindow" Height = "350" Width = "604">
<Grid>
<TextBox x:Name = "textBox" HorizontalAlignment = "Left"
Height = "241" Margin = "70,39,0,0" TextWrapping = "Wrap"
VerticalAlignment = "Top" Width = "453"/>
</Grid>
</Window>
นี่คือการอ่านไฟล์ที่มีการจัดการข้อยกเว้นใน C #
using System;
using System.IO;
using System.Windows;
namespace WPFExceptionHandling {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
ReadFile(0);
}
void ReadFile(int index) {
string path = @"D:\Test.txt";
StreamReader file = new StreamReader(path);
char[] buffer = new char[80];
try {
file.ReadBlock(buffer, index, buffer.Length);
string str = new string(buffer);
str.Trim();
textBox.Text = str;
}
catch (Exception e) {
MessageBox.Show("Error reading from "+ path + "\nMessage = "+ e.Message);
}
finally {
if (file != null) {
file.Close();
}
}
}
}
}
เมื่อคุณคอมไพล์และรันโค้ดข้างต้นมันจะสร้างหน้าต่างต่อไปนี้ซึ่งข้อความจะปรากฏขึ้นภายในกล่องข้อความ
เมื่อมีข้อยกเว้นเพิ่มขึ้นหรือคุณโยนด้วยตนเอง (ตามรหัสต่อไปนี้) กล่องข้อความจะแสดงข้อผิดพลาด
using System;
using System.IO;
using System.Windows;
namespace WPFExceptionHandling {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
ReadFile(0);
}
void ReadFile(int index) {
string path = @"D:\Test.txt";
StreamReader file = new StreamReader(path);
char[] buffer = new char[80];
try {
file.ReadBlock(buffer, index, buffer.Length);
string str = new string(buffer);
throw new Exception();
str.Trim();
textBox.Text = str;
}
catch (Exception e) {
MessageBox.Show("Error reading from "+ path + "\nMessage = "+ e.Message);
}
finally {
if (file != null) {
file.Close();
}
}
}
}
}
เมื่อมีการเพิ่มข้อยกเว้นในขณะเรียกใช้โค้ดข้างต้นจะแสดงข้อความต่อไปนี้
เราขอแนะนำให้คุณรันโค้ดด้านบนและทดลองกับคุณสมบัติต่างๆ