Создание роботов с помощью S#. Часть 1. Обработка исключений
Самое главное в роботе — это обработка исключений. У нас в роботе могут быть запущено множество различных стратегий, и исключение в одном из роботов или ошибка в 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);
- мы получим сообщение об ошибке, а не проглотим его.
Автор статьи — Вадим Чижов