This is a follow up to my initial question and I would like to present my findings and ask for corrections, ideas and insights. My findings (or rather interpretations) come from people's answers to my previous question, reading MSDN .NET 3.5 documentation and debugging .NET 3.5 code. I hope this will be of value to someone who was wondering like me how to detect when an application terminates.
Events:
System.AppDomain.CurrentDomain.ProcessExit: raised when process exits, e.g. after the default AppDomain and everything else was unloaded [Total execution time is limited to just 3 seconds!]. For WPF, use System.Windows.Application.Exit instead. For Windows Forms, run code after Application.Run(...) in main method.
System.AppDomain.CurrentDomain.DomainUnload: raised when an AppDomain other than default AppDomain unloads, e.g. when running classes with unit testing frameworks (MbUnit with TestDriven.NET).
System.AppDomain.CurrentDomain.UnhandledException: (if handled in default AppDomain:) raised for any unhandled exception in any thread, no matter what AppDomain the thread started in. This means, this can be used as the catch-all for all unhandled exceptions.
System.Windows.Application.Exit: raised when WPF application (i.e. the default AppDomain) exits gracefully. Override System.Windows.Application.OnExit to take advantage of it.
Finalizers (destructors in C#): run when garbage collector frees unmanaged resources. [Total execution time is limited!].
Order of events:
WPF application: graceful exit
System.Windows.Application.Exit
System.AppDomain.CurrentDomain.ProcessExit
Finalizers
WPF application: unhandled exception
System.AppDomain.CurrentDomain.UnhandledException
MbUnit running inside TestDriven.NET: passed test (graceful exit)
System.AppDomain.CurrentDomain.DomainUnload
Finalizers
MbUnit running inside TestDriven.NET: failed test (unhandled exceptions are handled by MbUnit)
AppDomain.CurrentDomain.DomainUnload
Finalizers
Questions:
Are my interpretations/findings correct?
Do you know of more details that I have
left out? E.g. what is the total
execution time for finalizers?
Do you know of any other events /
ideas that I be aware of?
What events are there and what order do they get raised in other applications, e.g. Windows Forms, Web Service, ASP.NET web site, etc?
Prompted by ssg31415926's question/answer (this question is a bit reversed), there's also Application.SessionEnding which is called when the when the user logs off or shuts down. It is called before the Exit event.
When Dispatcher.BeginInvokeShutdown() is called, Application.Exit will not be called.
The default timeout for a finalizer's execution is 2 seconds.
You write:
System.AppDomain.CurrentDomain.UnhandledException: (if handled in default AppDomain:) raised for any unhandled exception in any thread, no matter what AppDomain the thread started in. This means, this can be used as the catch-all for all unhandled exceptions.
I do not think that this is correct. Try the following code:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace AppDomainTestingUnhandledException
{
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException +=
(sender, eventArgs) => Console.WriteLine("Something went wrong! " + args);
var ad = AppDomain.CreateDomain("Test");
var service =
(RunInAnotherDomain)
ad.CreateInstanceAndUnwrap(
typeof(RunInAnotherDomain).Assembly.FullName, typeof(RunInAnotherDomain).FullName);
try
{
service.Start();
}
catch (Exception e)
{
Console.WriteLine("Crash: " + e.Message);
}
finally
{
AppDomain.Unload(ad);
}
}
}
class RunInAnotherDomain : MarshalByRefObject
{
public void Start()
{
Task.Run(
() =>
{
Thread.Sleep(1000);
Console.WriteLine("Uh oh!");
throw new Exception("Oh no!");
});
while (true)
{
Console.WriteLine("Still running!");
Thread.Sleep(300);
}
}
}
}
As far as I can tell, the UnhandledException handler is never called, and the thread will just silently crash (or nag at you if you run it in the debugger).
Just add a new event on your main form:
private void frmMain_Load(object sender, EventArgs e)
{
Application.ApplicationExit += new EventHandler(this.WhenItStopsDoThis);
}
private void WhenItStopsDoThis(object sender, EventArgs e)
{
//Program ended. Do something here.
}
Related
I wanted to set some handler for all the unexpected exceptions that I might not have caught inside my code. In Program.Main() I used the following code:
AppDomain.CurrentDomain.UnhandledException
+= new UnhandledExceptionEventHandler(ErrorHandler.HandleException);
But it didn't work as I expected. When I started the application in debugging mode and threw an exception it did call the handler, but afterwards the exception helper in Visual Studio popped up as if the exception occurred without any handling. I tried Application.Exit() inside the handler but it didn't work as well.
What I would like to achieve is that the exception is handled with my handler and then the application closes nicely. Is there any other way to do it or am I using the code above in the wrong way?
Normally I use something like this to try and catch all unexpected top-level exceptions.
using System;
static class Program
{
[STAThread]
static void Main(string[] argv)
{
try
{
AppDomain.CurrentDomain.UnhandledException += (sender,e)
=> FatalExceptionObject(e.ExceptionObject);
Application.ThreadException += (sender,e)
=> FatalExceptionHandler.Handle(e.Exception);
// whatever you need/want here
Application.Run(new MainWindow());
}
catch (Exception huh)
{
FatalExceptionHandler.Handle(huh);
}
}
static void FatalExceptionObject(object exceptionObject) {
var huh = exceptionObject as Exception;
if (huh == null) {
huh = new NotSupportedException(
"Unhandled exception doesn't derive from System.Exception: "
+ exceptionObject.ToString()
);
}
FatalExceptionHandler.Handle(huh);
}
}
Maybe it is something you find helpful too? This main code routes all three ways of catching unexpected top-level exceptions through one method call. All you now need is a static class FatalExceptionHandler that includes your top-level exception handling in its Handle method.
And really, any application developer knows there are really just two things to do there:
Show/log the exception like you see fit
Make sure you exit/kill the application process
If you think item two is strange, remember that we only bother to do this in the first place for really exceptional situations. These things are probably bugs that need changes to your application to be accurately addressed. Any other exception handling - the functional kind - should be lower down inside your actual program code, catching specific kinds of exceptions where this makes sense and handling them there in the way that makes sense. Anything else should bubble up to your FatalExceptionHandler to make itself known and stop the possibly crippled program from working from corrupted state
Dead programs tell no lies... ;-)
It's because you're running it through Visual Studio in Debug mode. If you release and install your app somewhere else, nothing but your global exception handler will be processed.
Note that unhandled exceptions are still pretty fatal; you can only really use this for logging, or maybe some hasty close-down. Neither this nor Application.ThreadException can be used as a global sink for errors.
The better approach is to add proper handling - for example, around your entire Main() logic. Note that even this can't catch a few exceptions, such as errors during form-load (which get particularly nasty - you can catch them with a debugger attached, but not without).
Perhaps what you're looking for is Environment.Exit(int errorcode)
That behavior is by design.
But there is a work-around.
Either you call Process.GetCurrentProcess().Kill(); within the handler, or simply do not let the handler end.
Check out the example:
class Program
{
void Run()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Console.WriteLine("Press enter to exit.");
do
{
(new Thread(delegate()
{
throw new ArgumentException("ha-ha");
})).Start();
} while (Console.ReadLine().Trim().ToLowerInvariant() == "x");
Console.WriteLine("last good-bye");
}
int r = 0;
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Interlocked.Increment(ref r);
Console.WriteLine("handled. {0}", r);
Console.WriteLine("Terminating " + e.IsTerminating.ToString());
Thread.CurrentThread.IsBackground = true;
Thread.CurrentThread.Name = "Dead thread";
while (true)
Thread.Sleep(TimeSpan.FromHours(1));
//Process.GetCurrentProcess().Kill();
}
static void Main(string[] args)
{
Console.WriteLine("...");
(new Program()).Run();
}
}
This should not be a default sink for exceptions, surely.
But this should be done to report exceptions gracefully.
Note: if you're application is a Windows Forms application, don't forget to:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
... or else the application will terminate, even if you handle the exceptions with the handlers specified by the other answers.
I started a blank WPF application (shown below) to implement HockeyApp crash reporting. When the program starts, a window popups up with a single button for the user to press. When the user clicks it the handler attempts to divide by zero and crashes the app. I was receiving crash reports and everything was running smoothly UNTIL I mimicked our bigger system's error catching method, which was to use the DispatcherUnhandledException Event Handler to catch "uncaught" exceptions and then call System.Environment.Exit(0) to gracefully end anything in the background. Now the HockeyApp api isn't sending crash reports. I'm wondering if catching the exceptions at a higher level makes HockeyApp think "Oh, they got things under control" and won't register a "crash."
I'm currently talking to the HockeyApp support staff about this, but I'm wondering if anyone else has had this problem. Should I take out the Exit(0) line, or is there a better practice for exiting an app when we have an uncaught exception? I've tried changing the error code from 0 to 574 (ERROR_UNHANDLED_EXCEPTION) with no result. I don't believe there's any data that we need to save, other than what the HockeyApp api already has.
App class:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
RegisterHockeyAppCrashReporting();
Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
}
private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
System.Environment.Exit(0);
}
private async void RegisterHockeyAppCrashReporting()
{
HockeyClient.Current.Configure(AppConstants.APP_ID)
.SetContactInfo(AppConstants.USER_NAME, AppConstants.USER_EMAIL);
await HockeyClient.Current.SendCrashesAsync(true);
}
}
MainWindow class:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var zero = 0;
var number = 1;
var crash = number / zero;
}
}
Environement.Exit terminates your application immediately. So, I guess, there's nothing strange in the fact that Hockey does not do anything.
Exit terminates an application immediately, even if other threads are
running. If the return statement is called in the application entry
point, it causes an application to terminate only after all foreground
threads have terminated.
If Exit is called from a try or catch block, the code in any finally
block does not execute. If the return statement is used, the code in
the finally block does execute.
Best practices tend to be opinion based and situation dependent. We, for example, log stack trace on unhandled exceptions and then call Environement.FailFast in our UWP app (we do not use Hockey apps though). Our logic is simple - our logger facility is probably alive but we're not so sure about the rest of the app. If even the logger facility is not functional than we won't be able to do anything anyway. Imho Exit and FailFast are the last steps that should only be used when you have no hope of restoring some valid state.
I wanted to set some handler for all the unexpected exceptions that I might not have caught inside my code. In Program.Main() I used the following code:
AppDomain.CurrentDomain.UnhandledException
+= new UnhandledExceptionEventHandler(ErrorHandler.HandleException);
But it didn't work as I expected. When I started the application in debugging mode and threw an exception it did call the handler, but afterwards the exception helper in Visual Studio popped up as if the exception occurred without any handling. I tried Application.Exit() inside the handler but it didn't work as well.
What I would like to achieve is that the exception is handled with my handler and then the application closes nicely. Is there any other way to do it or am I using the code above in the wrong way?
Normally I use something like this to try and catch all unexpected top-level exceptions.
using System;
static class Program
{
[STAThread]
static void Main(string[] argv)
{
try
{
AppDomain.CurrentDomain.UnhandledException += (sender,e)
=> FatalExceptionObject(e.ExceptionObject);
Application.ThreadException += (sender,e)
=> FatalExceptionHandler.Handle(e.Exception);
// whatever you need/want here
Application.Run(new MainWindow());
}
catch (Exception huh)
{
FatalExceptionHandler.Handle(huh);
}
}
static void FatalExceptionObject(object exceptionObject) {
var huh = exceptionObject as Exception;
if (huh == null) {
huh = new NotSupportedException(
"Unhandled exception doesn't derive from System.Exception: "
+ exceptionObject.ToString()
);
}
FatalExceptionHandler.Handle(huh);
}
}
Maybe it is something you find helpful too? This main code routes all three ways of catching unexpected top-level exceptions through one method call. All you now need is a static class FatalExceptionHandler that includes your top-level exception handling in its Handle method.
And really, any application developer knows there are really just two things to do there:
Show/log the exception like you see fit
Make sure you exit/kill the application process
If you think item two is strange, remember that we only bother to do this in the first place for really exceptional situations. These things are probably bugs that need changes to your application to be accurately addressed. Any other exception handling - the functional kind - should be lower down inside your actual program code, catching specific kinds of exceptions where this makes sense and handling them there in the way that makes sense. Anything else should bubble up to your FatalExceptionHandler to make itself known and stop the possibly crippled program from working from corrupted state
Dead programs tell no lies... ;-)
It's because you're running it through Visual Studio in Debug mode. If you release and install your app somewhere else, nothing but your global exception handler will be processed.
Note that unhandled exceptions are still pretty fatal; you can only really use this for logging, or maybe some hasty close-down. Neither this nor Application.ThreadException can be used as a global sink for errors.
The better approach is to add proper handling - for example, around your entire Main() logic. Note that even this can't catch a few exceptions, such as errors during form-load (which get particularly nasty - you can catch them with a debugger attached, but not without).
Perhaps what you're looking for is Environment.Exit(int errorcode)
That behavior is by design.
But there is a work-around.
Either you call Process.GetCurrentProcess().Kill(); within the handler, or simply do not let the handler end.
Check out the example:
class Program
{
void Run()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Console.WriteLine("Press enter to exit.");
do
{
(new Thread(delegate()
{
throw new ArgumentException("ha-ha");
})).Start();
} while (Console.ReadLine().Trim().ToLowerInvariant() == "x");
Console.WriteLine("last good-bye");
}
int r = 0;
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Interlocked.Increment(ref r);
Console.WriteLine("handled. {0}", r);
Console.WriteLine("Terminating " + e.IsTerminating.ToString());
Thread.CurrentThread.IsBackground = true;
Thread.CurrentThread.Name = "Dead thread";
while (true)
Thread.Sleep(TimeSpan.FromHours(1));
//Process.GetCurrentProcess().Kill();
}
static void Main(string[] args)
{
Console.WriteLine("...");
(new Program()).Run();
}
}
This should not be a default sink for exceptions, surely.
But this should be done to report exceptions gracefully.
Note: if you're application is a Windows Forms application, don't forget to:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
... or else the application will terminate, even if you handle the exceptions with the handlers specified by the other answers.
I am very new to c# programming, so that in mind:
I have an in-memory data object with data I need to save the information when(if) my application were to crash OR closed. Is there a way to do this deterministically or reliably?
I have been looking at destructors
~MyObjectName(){}
finalizers and Dispose(),
but as far as I understand none of these will do reliably what I want?
Currently I am using the destructor, and it works when I am closing the program, but this doesn't mean it will work on crashing, or always.
Should I be looking at events as well?
There is no 100% reliable mechanism that you can use to save data (or do anything else for that matter) when a process (any process, not just a .Net process) terminates - most processes can be terminated at any point using the "End Process" option in the task manager, when this happens the process is immediately killed. As a more extreme example the power cord could be pulled out the back of the machine.
If its not 100% necessary that this data object be up-to-date and saved once the process is killed then the AppDomain.UnhandledException Event may suffice.
If its absolutely 100% necessary that this be the case then you need to be continuously saving this information as the process is running - there is absolutely no guarentee that you will get a chance to do it at a later date. This is how databases operate, no transaction returns until some record of the change has been recorded to disk in some format (e.g. a transaction log). This is what the D stands for in ACID.
I believe you are looking for catching unhandled exceptions? something like this:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.Run(new Form1());
}
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception");
// here you can log the exception ...
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled UI Exception");
// here you can log the exception ...
}
This example shows how to manage all exceptions that haven't been
caught in the try-catch sections (in Windows Forms application).
The UnhandledException event handles uncaught exceptions thrown from
the main UI thread. The ThreadException event handles uncaught
exceptions thrown from non-UI threads.
You can achieve this with windbg.
Keep a breakpoint in zwterminateprocess method in windbg. This method will be called when your application exits.
when the breakpoint is reached , use !dumpheap -type MyObjectName to get the address of your object
Use !dumpobject "address of MyObjectName" to know the values inside the object
We have a WPF application where parts of it may throw exceptions at runtime. I'd like to globally catch any unhandled exceptions and log them, but otherwise continue program execution as if nothing happened (kinda like VB's On Error Resume Next).
Is this possible in C#? And if so, where exactly would I need to put the exception handling code?
Currently I can't see any single point where I could wrap a try/catch around and which would catch all exceptions that could occur. Even then, I would have left whatever has been executed because of the catch. Or am I thinking in horribly wrong directions here?
ETA: Because many people below pointed it out: The application is not for controlling nuclear power plants. If it crashes, it's not that big a deal, but it throws random exceptions that are mostly UI-related that are a nuisance in the context where it would be used. There were (and probably still are) a few of those and since it uses a plugin architecture and may be extended by others (also students in that case; so no experienced developers that are able to write completely error-free code).
As for the exceptions that get caught: I do log them to a log file, including the complete stack trace. That was the whole point of that exercise. Just to counter those people that were taking my analogy to VB's OERN too literally.
I know that blindly ignoring certain classes of errors is dangerous and might corrupt my application instance. As said before, this program isn't mission-critical for anyone. No-one in their right mind would bet the survival of the human civilization on it. It's simply a little tool for testing certain design approaches wrt. software engineering.
For the immediate use of the application there are not many things that can happen on an exception:
No exception handling – error dialog and application exit. Experiment has to be repeated, though likely with another subject. No errors have been logged, which is unfortunate.
Generic exception handling – benign error trapped, no harm done. This should be the common case judged from all errors we were seeing during development. Ignoring this kind of errors should have no immediate consequences; the core data structures are tested well enough that they will easily survive this.
Generic exception handling – serious error trapped, possibly crash at a later point. This may happen rarely. We've never seen it so far. The error is logged anyway and a crash might be inevitable. So this is conceptually similar to the very first case, except that we have a stack trace. And in the majority of cases the user won't even notice.
As for the experiment data generated by the program: A serious error would at worst just cause no data to be recorded. Subtle changes that change the result of the experiment ever so slightly are pretty unlikely. And even in that case, if the results seem dubious the error was logged; one can still throw away that data point if it's a total outlier.
To summarize: Yes, I consider myself still at least partially sane and I don't consider a global exception handling routine which leaves the program running to be necessarily totally evil. As said twice before, such a decision might be valid, depending on the application. In this case it was judged a valid decision and not total and utter bullshit. For any other application that decision might look different. But please don't accuse me or the other people who worked on that project to potentially blow up the world just because we're ignoring errors.
Side note: There is exactly one user for that application. It's not something like Windows or Office that gets used by millions where the cost of having exceptions bubble to the user at all would be very different in the first place already.
Use the Application.DispatcherUnhandledException Event. See this question for a summary (see Drew Noakes' answer).
Be aware that there'll be still exceptions which preclude a successful resuming of your application, like after a stack overflow, exhausted memory, or lost network connectivity while you're trying to save to the database.
Example code using NLog that will catch exceptions thrown from all threads in the AppDomain, from the UI dispatcher thread and from the async functions:
App.xaml.cs :
public partial class App : Application
{
private static Logger _logger = LogManager.GetCurrentClassLogger();
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
SetupExceptionHandling();
}
private void SetupExceptionHandling()
{
AppDomain.CurrentDomain.UnhandledException += (s, e) =>
LogUnhandledException((Exception)e.ExceptionObject, "AppDomain.CurrentDomain.UnhandledException");
DispatcherUnhandledException += (s, e) =>
{
LogUnhandledException(e.Exception, "Application.Current.DispatcherUnhandledException");
e.Handled = true;
};
TaskScheduler.UnobservedTaskException += (s, e) =>
{
LogUnhandledException(e.Exception, "TaskScheduler.UnobservedTaskException");
e.SetObserved();
};
}
private void LogUnhandledException(Exception exception, string source)
{
string message = $"Unhandled exception ({source})";
try
{
System.Reflection.AssemblyName assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName();
message = string.Format("Unhandled exception in {0} v{1}", assemblyName.Name, assemblyName.Version);
}
catch (Exception ex)
{
_logger.Error(ex, "Exception in LogUnhandledException");
}
finally
{
_logger.Error(exception, message);
}
}
AppDomain.UnhandledException Event
This event provides notification of uncaught exceptions. It allows the
application to log information about the exception before the system
default handler reports the exception to the user and terminates the
application.
public App()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
}
static void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception) args.ExceptionObject;
Console.WriteLine("MyHandler caught : " + e.Message);
Console.WriteLine("Runtime terminating: {0}", args.IsTerminating);
}
If the UnhandledException event is handled in the default application
domain, it is raised there for any unhandled exception in any thread,
no matter what application domain the thread started in. If the thread
started in an application domain that has an event handler for
UnhandledException, the event is raised in that application domain. If
that application domain is not the default application domain, and
there is also an event handler in the default application domain, the
event is raised in both application domains.
For example, suppose a thread starts in application domain "AD1",
calls a method in application domain "AD2", and from there calls a
method in application domain "AD3", where it throws an exception. The
first application domain in which the UnhandledException event can be
raised is "AD1". If that application domain is not the default
application domain, the event can also be raised in the default
application domain.
In addition what others mentioned here, note that combining the Application.DispatcherUnhandledException (and its similars) with
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="1" />
</runtime>
</configuration>
in the app.config will prevent your secondary threads exception from shutting down the application.
Here is complete example using NLog
using NLog;
using System;
using System.Windows;
namespace MyApp
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private static Logger logger = LogManager.GetCurrentClassLogger();
public App()
{
var currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var ex = (Exception)e.ExceptionObject;
logger.Error("UnhandledException caught : " + ex.Message);
logger.Error("UnhandledException StackTrace : " + ex.StackTrace);
logger.Fatal("Runtime terminating: {0}", e.IsTerminating);
}
}
}
in Wpf application Project follow this Steps:
in App.xaml.cs file:
using 'System.Windows.Threading'
create App_DispatcherUnhandledException method same example.
example:
using System.Windows;
using System.Windows.Threading;
namespace Test
{
public partial class App : Application
{
void App_DispatcherUnhandledException(object sender,
DispatcherUnhandledExceptionEventArgs e)
{
// Process unhandled exception
// Prevent default unhandled exception processing
e.Handled = true;
}
}
}
in App.xaml:
add DispatcherUnhandledException="App_DispatcherUnhandledException"
for Example:
<Application x:Class="eValGr.UI.Light.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:eValGr.UI.Light"
DispatcherUnhandledException="Application_DispatcherUnhandledException">
<Application.Resources>
</Application.Resources>
</Application>
Like "VB's On Error Resume Next?" That sounds kind of scary. First recommendation is don't do it. Second recommendation is don't do it and don't think about it. You need to isolate your faults better. As to how to approach this problem, it depends on how you're code is structured. If you are using a pattern like MVC or the like then this shouldn't be too difficult and would definitely not require a global exception swallower. Secondly, look for a good logging library like log4net or use tracing. We'd need to know more details like what kinds of exceptions you're talking about and what parts of your application may result in exceptions being thrown.