Reputation: 3361
Currently my application capture unhandled exceptions as follows:
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
although, when an exception it happens like this (eg):
TimeSpan toExecute = AnyMethod();
Observable.Timer(toExecute).Take(1).Subscribe((r) =>
{
Trace.WriteLine("Subscribe");
throw new Exception(); // simulation..
});
The exception keeps repeating itself infinitely (in debug).
Although in release mode or out of visual studio the application is finalized (standard behavior of AppDomain.CurrentDomain.UnhandledException
How to avoid or change this behavior?
My goal is to run the code only once. Independent if an exception occurs or not. One of the requirements is that it is triggered by a timer. Something else .. if there is an exception it should be treated by DispatcherUnhandledException or UnobservedTaskException or similiar (this prevents me from write a try catch for each subscription and shutdown of the application)
Upvotes: 2
Views: 774
Reputation: 3586
Your code triggers AppDomain.CurrentDomain.UnhandledException
, which terminates application execution for .NET 2.0 and higher. If you debug that code in Visual Studio, you get Unhandled Exception notifications repeatedly.
In the .NET Framework versions 1.0 and 1.1, an unhandled exception that occurs in a thread other than the main application thread is caught by the runtime and therefore does not cause the application to terminate. Thus, it is possible for the UnhandledException event to be raised without the application terminating. In the .NET Framework version 2.0, this backstop for unhandled exceptions in child threads was removed, because the cumulative effect of such silent failures included performance degradation, corrupted data, and lockups, all of which were difficult to debug. For more information, including a list of cases in which the runtime does not terminate, see Exceptions in Managed Threads.
See documentation for AppDomain.UnhandledException Event.
For those who are curious, here's stack trace (for .NET 3.5 & Reactive Extensions Version 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)
Upvotes: 2