This article is currently in the process of being translated into Hebrew (~94% done).
טיפול בחריגות (Exceptions) עם WPF
אם אתה מכיר את #c או שפה דוט-נטית אחרת, הטיפול בחריגות (exception) לא חדש לך: אם מקטע של קוד עלול לבצע פעולה חריגה, אזי יש לעטוף אותו ב-try-catch על מנת לטפל בחריגות. נבחן את הדוגמה הבאה:
private void Button_Click(object sender, RoutedEventArgs e)
{
string s = null;
s.Trim();
}
ברור שכאן יש חריגה - אנו מנסים לקרוא לפונקציה Trim עבור משתנה שערכו הנוכחי null. אם לא נתיחס לחריגה כאן התוכנית "תתרסק" ומערכת ההפעלה תצטרך לטפל בבעיה. כפי שניתן לראות זה לא לגמרי ידידותי למשתמש:
במקרה הזה שמשתמש יאלץ לסגור את התוכנה. הכל בגלל שגיאה שאפשר היה למנוע אותה בקלות. אם לדעתך משהו עלול להשתבש במקטע של קוד, יש לעטוף אותו ב- try-catch, כמו כאן:
private void Button_Click(object sender, RoutedEventArgs e)
{
string s = null;
try
{
s.Trim();
}
catch(Exception ex)
{
MessageBox.Show("A handled exception just occurred: " + ex.Message, "Exception Sample", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
חריגות עלולות להתרחש בשורות קוד פשוטות. כדי לא לעטוף של שורה ב- try-catch, ניתן לטפל בחריגות באופן גורף. ניתן לעשות זאת ע"י טיפול באירוע DispatcherUnhandledException של Application. אם נרשמים לאירוע כזה (ראה שורה DispatcherUnhandledException="Application_DispatcherUnhandledException" ב- XAML המתאר Application, למטה), WPF יקרא לפונקציה שאמורה לטפל DispatcherUnhandledException אם קרתה חריגה שלא טופלה בקוד. להלהן דוגמה המבוססת על דוגמאות קודמות:
<Window x:Class="WpfTutorialSamples.WPF_Application.ExceptionHandlingSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ExceptionHandlingSample" Height="200" Width="200">
<Grid>
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click">
Do something bad!
</Button>
</Grid>
</Window>
using System;
using System.Windows;
namespace WpfTutorialSamples.WPF_Application
{
public partial class ExceptionHandlingSample : Window
{
public ExceptionHandlingSample()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
string s = null;
try
{
s.Trim();
}
catch(Exception ex)
{
MessageBox.Show("A handled exception just occurred: " + ex.Message, "Exception Sample", MessageBoxButton.OK, MessageBoxImage.Warning);
}
s.Trim();
}
}
}
שים לב שפונקציה Trim נקראת פעם נוספת מחוץ ל- try-catch. קריאה לפונקציה, כאמור, גורמת לחריגה. החריגה הראשונה מטופלת בתוך try-catch ואילו השניה - לא. עבור החריגה השניה אנו זקוקים ל-App.xaml
<Application x:Class="WpfTutorialSamples.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DispatcherUnhandledException="Application_DispatcherUnhandledException"
StartupUri="WPF Application/ExceptionHandlingSample.xaml">
<Application.Resources>
</Application.Resources>
</Application>
using System;
using System.Windows;
namespace WpfTutorialSamples
{
public partial class App : Application
{
private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show("An unhandled exception just occurred: " + e.Exception.Message, "Exception Sample", MessageBoxButton.OK, MessageBoxImage.Error);
e.Handled = true;
}
}
}
טיפלנו בחריגה בדומה לטיפול שנעשה בתוך try-catch, תוך שימוש בהודעת טקסט ואייקון חריפים יותר. שים לב לכך שבתוך הפונקציה המטפלת בחריגה מופיעה שורה עם e.Handled = true. זה מסמן ל- WPF שטיפלנו בחריגה ואין צורך להמשיך לטפל בה.
סיכום
טיפול בחריגות הינו מאוד חשוב בכל אפליקציה. WPF ו- .NET מאפשרים לעשות זאת הן באופן מקומי (ע"י שימוש ב- try-catch) והן באופן גלובלי. צריך הלשתדל לטפל בחריגות באופן מקומי מפני שהיפול המקומי יכול להיות יותר ספציפי ולהתיחס לפרטי החריגה. הטיפול הגלובלי הוא הגנה מפני חריגות שלא התייחסנו אליהן.