Исключение повторяется бесконечно, используя Rx

В настоящее время мое приложение фиксирует необработанные исключения следующим образом:

AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

хотя, когда исключение происходит так (например):

        TimeSpan toExecute = AnyMethod();
        Observable.Timer(toExecute).Take(1).Subscribe((r) =>
        {
            Trace.WriteLine("Subscribe");
            throw new Exception(); // simulation..
        });

Исключение повторяется бесконечно (при отладке). Хотя в режиме релиза или вне Visual Studio приложение завершено (стандартное поведение AppDomain.CurrentDomain.UnhandledException
Как избежать или изменить это поведение?


Моя цель - запустить код только один раз. Независимо, если исключение происходит или нет. Одним из требований является то, что он запускается таймером. Что-то еще.. если есть исключение, оно должно быть обработано DispatcherUnhandledException или UnobservedTaskException или подобным образом (это мешает мне написать контрольный улов для каждой подписки и завершения работы приложения)

1 ответ

Ваш код срабатывает AppDomain.CurrentDomain.UnhandledException, что прекращает выполнение приложения для.NET 2.0 и выше. Если вы отлаживаете этот код в Visual Studio, вы неоднократно получаете уведомления об необработанных исключениях.

В.NET Framework версий 1.0 и 1.1 необработанное исключение, которое возникает в потоке, отличном от основного потока приложения, перехватывается средой выполнения и, следовательно, не приводит к завершению приложения. Таким образом, событие Unhandled Exception может быть вызвано без завершения приложения. В.NET Framework версии 2.0 эта обратная остановка для необработанных исключений в дочерних потоках была удалена, поскольку кумулятивный эффект таких тихих отказов включал в себя снижение производительности, повреждение данных и блокировки, которые трудно было отладить. Для получения дополнительной информации, включая список случаев, когда среда выполнения не завершается, см. Исключения в управляемых потоках.

См. Документацию для события AppDomain.UnhandledException.

Для тех, кому интересно, вот трассировка стека (для.NET 3.5 и Reactive Extensions версии 1.0.10621.0):

System.Exception: Exception of type 'System.Exception' was thrown.

   at yournamespace.MainWindow.<Button_Click>b__0(Int64 r) in path\MainWindow.xaml.cs:line XX
   at System.Reactive.AnonymousObserver`1.Next(T value)
   at System.Reactive.AbstractObserver`1.OnNext(T value)
   at System.Reactive.AnonymousObservable`1.AutoDetachObserver.Next(T value)
   at System.Reactive.AbstractObserver`1.OnNext(T value)
   at System.Reactive.Linq.Observable.<>c__DisplayClass2ff`1.<>c__DisplayClass301.<Take>b__2fe(TSource x)
   at System.Reactive.AnonymousObserver`1.Next(T value)
   at System.Reactive.AbstractObserver`1.OnNext(T value)
   at System.Reactive.AnonymousObservable`1.AutoDetachObserver.Next(T value)
   at System.Reactive.AbstractObserver`1.OnNext(T value)
   at System.Reactive.Linq.Observable.<>c__DisplayClass35b.<>c__DisplayClass35d.<Timer>b__35a()
   at System.Reactive.Concurrency.Scheduler.Invoke(IScheduler scheduler, Action action)
   at System.Reactive.Concurrency.ThreadPoolScheduler.<>c__DisplayClass5`1.<Schedule>b__3(Object _)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading._TimerCallback.PerformTimerCallback(Object state)
Другие вопросы по тегам