异常无限重复,使用Rx

本文关键字:使用 Rx 无限 异常 | 更新日期: 2023-09-27 17:49:54

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

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或类似的处理(这可以防止我为每个订阅和关闭应用程序编写一个try catch)

异常无限重复,使用Rx

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

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

参见AppDomain的文档。UnhandledException事件。

对于那些好奇的人,这里是堆栈跟踪(对于。net 3.5 &响应式扩展版本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)