This article has been localized into Russian by the community.
Обработка исключений в 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.Warning); e.Handled = true; } } }


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