TOC

This article is currently in the process of being translated into Finnish (~60% done).

A WPF application:

Handling exceptions in WPF

Jos C# tai jokin muu WPF:n yhteyteen sopiva .NET pohjainen kieli on sinulle tuttu, poikkeusten käsittelyn ei pitäisi olla sinulle uutta: Milloin ikinä sinulla on pala koodia, joka saattaa antaa poikkeuksen, se kuuluisi ympäröidä try-catch blokilla, jotta poikkeus voidaan käsitellä sulavasti. Katso vaikka tämä esimerkki:

private void Button_Click(object sender, RoutedEventArgs e)
{
	string s = null;
	s.Trim();
}

Itsestäänselvästikin se tulee kaatumaan, koska yritän ajaa Trim() metodia muuttujalle joka on tällä hetkellä null. Jos poikkeusta ei käsitellä, sovelluksesi kaatuu ja Windows joutuu käsittelemään ongelman. Kuten huomaat, se ei ole kovin käyttäjäystävällistä:

Tässä tapauksessa käyttäjä joutuisi sulkemaan sovelluksen vain pienen ja helposti estettävän virheen vuoksi. Joten, jos tiedät että asiat saattavat mennä pieleen, sinun tulisi kokeilla try-catch blokin käyttöä, esimerkiksi näin:

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);
	}
}

Toisaalta, joskus kaikista yksinkertaisinkin koodi voi antaa poikkeuksen, ja sen sijaan että jokainen koodirivi olisi ympäröity try-catch blokilla, WPF mahdollistaa käsittelemättömien poikkeuksien käsittelyn globaalisti. Tämä tehdään Application luokan DispatcherUnhandledException tapahtuman avulla. Jos se on tilattu, WPF kutsuu tilattua metodia kun sovellus antaa poikkeuksen, joka ei ole koodissa käsitelty. Tässä on esimerkki juuri läpikäydystä kokonaisuudesta:

<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();
		}
	}
}

Huomaa, että kutsun Trim() metodia ylimääräisen kerran try-catch blokin ulkopuolella, jotta ensimmäinen kutsu on käsitelty ja toinen ei. Toiselle tarvitsemme App.xaml magiaa:

<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;
		}
	}
}

We handle the exception much like the local one, but with a slightly different text and image in the message box. Also, notice that I set the e.Handled property to true. This tells WPF that we're done dealing with this exception and nothing else should be done about it.

Summary

Exception handling is a very important part of any application and fortunately, WPF and .NET makes it very easy to handle exceptions both locally and globally. You should handle exceptions locally when it makes sense and only use the global handling as a fallback mechanism, since local handling allows you to be more specific and deal with the problem in a more specialized way.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!