使用Rx无限重复异常

时间:2012-12-28 16:08:57

标签: c# system.reactive unhandled-exception

目前,我的应用程序捕获未处理的异常,如下所示:

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..
        });

异常会无限重复(在调试中)。 虽然在发布模式或视觉工作室之外,应用程序已完成(AppDomain.CurrentDomain.UnhandledException的标准行为
如何避免或改变这种行为?


我的目标是只运行一次代码。如果发生异常,则独立。其中一个要求是由计时器触发。 其他东西..如果有异常,它应该由DispatcherUnhandledException或UnobservedTaskException或类似处理(这可以防止我为每个订阅写一个try catch并关闭应用程序)

1 个答案:

答案 0 :(得分:2)

您的代码触发AppDomain.CurrentDomain.UnhandledException,终止.NET 2.0及更高版本的应用程序执行。如果在Visual Studio中调试该代码,则会反复收到Unhandled Exception通知。

  

在.NET Framework 1.0和1.1版中,出现未处理的异常   发生在主应用程序线程以外的线程中   由运行时捕获,因此不会导致应用程序   终止。因此,UnhandledException事件可能是   在没有申请终止的情况下提出。在.NET Framework中   版本2.0,这个支持子线程中的未处理异常   被删除了,因为这种无声失败的累积效应   包括性能下降,损坏的数据和锁定,所有   这很难调试。有关更多信息,包括列表   运行时未终止的情况,请参阅中的例外情况   管理线程。

请参阅AppDomain.UnhandledException Event的文档。

对于那些好奇的人,这里是堆栈跟踪(适用于.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)