TOC

This article has been localized into Russian by the community.

Приложение WPF:

Обработка исключений в WPF

Если Вы знакомы с C# или любым другим языком .NET, который можно использовать с WPF, то обработка исключений не вызовет у Вас больших затруднений: всякий раз, когда у Вас будет часть кода, которая с большой вероятностью может выдать исключение, Вам следует обернуть этот код в блок try-catch и изящно обработать исключение. Взгляните на следующий пример:

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

Очевидно, что код в примере написан некорректно. Я пытаюсь исполнить метод Trim() на переменной, которая в текущий момент приняла значение null. Если не обработать исключение, в Вашем приложении произойдет сбой и Windows придется разбираться с данной проблемой. Как вы видите, это не выглядит чересчур уж "user friendly":

В данном случае, пользователь мог бы форсировать закрытие программы, из-за такой простой и легкообходимой ошибки. Так что, если Вы знаете, о том, что с кодом что-то может пойти не так - используйте блок 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, можно воспользоваться механизмом WPF, позволяющим глобально обрабатывать исключений. Это становится возможным с использованием события DispatcherUnhandledException в классе Application. Если Вы подписываетесь на это событие, WPF будет вызывать метод этой подписки каждый раз, когда будет появляться исключение, необработанное в Вашем коде. Вот полный пример, основанный на механизме, который мы только что обсудили:

<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, и исключение появилось на первом вызове, а на втором - нет. Для второго нам необходимо немного магии 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;
		}
	}
}

В таком случае обработка исключения выглядит подобным образом как и для локальной обработки, с той лишь разницей, что сообщение об исключении содержит другой текст и изображение. Также, обратите внимание, что я определил свойство e.Handled как true. Это проинформирует WPF о том, что исключение уже обработано и с ним ничего не надо больше делать.

Итог

Обработка исключений - это очень важная часть любого приложения, и, к счастью, WPF и .NET делают этот процес легким, как для локальной, так и для глобальной обработки. Следует обрабатывать исключения локально, когда это необходимо, а глобальную обработку трактуйте как резервный механизм, поскольку локальная обработка позволит Вам управлять проблемой на более глубоком уровне.


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!