Создание роботов с помощью S#. Часть 1. Обработка исключений

Создание роботов с помощью S#. Часть 1. Обработка исключений
Atom
3/19/2012
FinDirector


Самое главное в роботе — это обработка исключений. У нас в роботе могут быть запущено множество различных стратегий, и исключение в одном из роботов или ошибка в UI потоке не должны приводить к падению всей программы. Тем не менее именно такое поведение характерно по умолчанию для .NET программы.
Далее считаем, что наш робот является WPF – приложением! В качестве теста используем следующий код:
Code
		private void Window_Loaded(object sender, RoutedEventArgs e)
		{
			Task.Factory.StartNew(ThrowException);
			ThrowException();
		}

		void ThrowException()
		{
			throw new Exception("ops!");
		}

Вначале мы кидаем исключение в отдельном потоке (а в стратегиях события могут вызываться асинхронно), а затем в UI потоке. Приложение упадет. Чтобы это исправить, необходимо сделать следующие правки.
В файле App.xaml.cs написать:
Code
		protected override void OnStartup(StartupEventArgs e)
		{
			base.OnStartup(e);

#if (DEBUG != true)
			// Don't handle the exceptions in Debug mode because otherwise the Debugger wouldn't
			// jump into the code when an exception occurs.
			DispatcherUnhandledException += AppDispatcherUnhandledException;
			AppDomain.CurrentDomain.UnhandledException += AppDomainUnhandledException;
#endif
		}

		private void AppDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
		{
			HandleException(e.Exception, false);
			e.Handled = true;
		}

		private static void AppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
		{
			HandleException(e.ExceptionObject as Exception, e.IsTerminating);
		}

		private static void HandleException(Exception e, bool isTerminating)
		{
			if (e == null) return;

			Trace.TraceError(e.ToString());

			if (!isTerminating)
			{
				MessageBox.Show(string.Format(CultureInfo.CurrentCulture, "Неизвестная ошибка: {0}", e.ToString()),
					"FinDirector", MessageBoxButton.OK, MessageBoxImage.Error);
			}
		}


Тем не менее, это не спасет от крэша наше приложение при необработанных исключениях не в UI потоке. В файл app.confg необходимо добавить строки:
Code
<runtime>
    <legacyUnhandledExceptionPolicy enabled="1" />
  </runtime>

Теперь:
  • приложение не будет падать при не критических исключениях (таких как OutOfMemory, StackOverflow);
  • мы получим сообщение об ошибке, а не проглотим его.

Автор статьи — Вадим Чижов




Attach files by dragging & dropping, , or pasting from the clipboard.

loading
clippy