Click here to Skip to main content
15,889,879 members
Articles / Desktop Programming / WPF

Global Exceptions Handling in WPF

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
2 Apr 2016CPOL2 min read 17K   3   1
Global exceptions handling in WPF

jQuery_Error_Handling

Are you sure you know the difference between the following events?

  • Dispatcher.UnhandledException
  • Application.DispatcherUnhandledException
  • AppDomain.UnhandledException
  • TaskScheduler.UnobservedTaskException

My dean in the university has always been saying that the first rule of programming is “Programs should not contain any errors” and the second rule of programming is “There are no programs written without errors”. So, sometimes, I’m sorry, but sh*t happens and uncaught exceptions occur and they fly freely until they reach the top of the execution stack, thus crushing your program. Global exceptions handling exists in order to react somehow to such horrible cases.
There is a bunch of events which fire up when an unhandled exception occurs. Let’s consider what events can help us. The most useful events as we already mentioned are:

  • Dispatcher.UnhandledException
  • Application.DispatcherUnhandledException
  • AppDomain.UnhandledException
  • TaskScheduler.UnobservedTaskException

Exception on a Dispatcher Thread

The difference between the first two events is a little bit slick. The second one catches exceptions from the main UI dispatcher thread, while the first one catches exceptions from a specific UI dispatcher thread. Usually, they are the same, because in 99% of the cases, WPF application has only one UI-thread and because of that, both the events catch exceptions from the same thread, from the main UI thread. The thing is that WPF is not restricted to have only one UI thread. You can create another UI thread with a corresponding Dispatcher. And in that case, you will have to attach your handler to the UnhandledException event of the first dispatcher and the second dispatcher. Chances that you will never face such a situation in your entire life are very high. So, generally speaking, you are free to attach handlers to any of these events.

Exception on a Worker Thread

An exception might be thrown from any worker thread in your application. In general, you can spawn the worker thread either by using Thread class directly or the modern API of Tasks. And regarding global exceptions handling, these cases are different. If an exception was thrown from a task, it can be caught only in the TaskScheduler.UnobservedTaskException. On the contrary, if an exception was thrown from any other thread, except the UI-thread and threads spawned by Tasks, it can be caught only in the AppDomain.UnhandledException event.

You can’t actually handle the exception in the AppDomain.UnhandledException event. You can just log it. If you want your application to stay alive, you need to add a directive in the configuration file of your application:

XML
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="1" />
</runtime>
</configuration>

Since the release of .NET 4.5, UnobservedTaskException does not kill the application. If you want to get back the old behavior, you should add the following directive in the configuration file:

XML
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<ThrowUnobservedTaskExceptions enabled="true"/>
</runtime>
</configuration>

By the way, exceptions occurred within Tasks will not be thrown until corresponding tasks are not collected by the GC.

Thank you for visiting my blog. Subscribe to my blog, don’t miss the next exciting post!

Filed under: .NET, C#, CodeProject, WPF Tagged: global-exception-handling, WPF Foundations

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
Questiongood patterns Pin
kiquenet.com4-Apr-16 12:28
professionalkiquenet.com4-Apr-16 12:28 
Great!
My question is about good patterns and practices about Error Handling

I have configuration file with system.web customErrors and system.webServer httpErrors, and custom Page with OnError method, Or maybe Global.asax Application_Error.
I thinking in ASP.NET Health Monitoring, and Failed Request Tracing, Module for UndhandledException or AppDomain.FirstChanceException event.

Good patterns and practices with

Asp-net-health-monitoring,
Failed Request Tracing,
httpErrors & customErrors,
Global.asax Application_Error,
BasePage OnError
UnhandledExceptionModule ( AppDomain.CurrentDomain.UnhandledException )

Others: AppDomain.FirstChanceException event.

with Ent.Library Logging y Exception Handling… ?

IIS:
Failed Request Tracing

ASP.NET:
Asp-net-health-monitoring
Global.asax Application_Error
Base Page OnError
web.config: customErrors, httpErrors
UnhandledExceptionModule ( AppDomain.CurrentDomain.UnhandledException )

MVC:
HandleErrorAttribute
Controller.OnException

Others: AppDomain.FirstChanceException event.

<customErrors mode="Off" defaultRedirect="~/Informacion/ErrorGenerico.aspx" redirectMode="ResponseRedirect">
<error statusCode="500" redirect="~/Informacion/ErrorGenerico.aspx"/>
<error statusCode="404" redirect="~/Informacion/Error404.aspx"/>
</customErrors>

<httpErrors existingResponse="Replace" errorMode="Custom">
<remove statusCode="404" subStatusCode="-1"/>
<error statusCode="404" subStatusCode="-1" path="/Informacion/ErrorGenerico.aspx?error=404" responseMode="ExecuteURL"/>
<remove statusCode="500" subStatusCode="-1"/>
<error statusCode="500" subStatusCode="-1" path="/Informacion/ErrorGenerico.aspx?error=500" responseMode="ExecuteURL"/>
</httpErrors>

(from 2004) https://msdn.microsoft.com/en-us/library/aa479319.aspx

Build a Really Useful ASP.NET Exception Engine like http://www.nullskull.com/articles/20030816.asp

Asp-net-health-monitoring,
mvolo.com/asp-net-health-monitoring-8-years-later/,

"rarely find people advocating the use of Health Monitoring",
"read 18 pages of MSDN documentation for every aspect of HM",

Failed Request Tracing
http://www.iis.net/learn/troubleshoot/using-failed-request-tracing/troubleshooting-failed-requests-using-tracing-in-iis

performance IIS 7.5 production if is enabled

http://stackoverflow.com/questions/24416447/iis-failed-request-tracing-performance-view-doesnt-show-time-spent
http://blogs.msdn.com/b/tess/archive/2008/08/19/troubleshooting-a-performance-issue-with-failed-request-tracing-and-appcmd-in-iis7.aspx
http://serverfault.com/questions/231216/keep-iis7-failed-request-tracing-as-a-sysadmin-only-diagnostic-tool

http://blogs.msdn.com/b/benjaminperkins/archive/2012/01/02/enable-and-activate-failed-request-tracing-rules.aspx

"Just don’t forget to turn off or manage the log files you are creating, they can have impact on performance if they grow unmanaged."

"the writting of IIS logs is not real time, the logs are stored in memory and at some point the IIS logs are written. The process is different than the one responding to web requests. So I would not expect the logging to have significant direct negative impact on the responding of a request. BUT, do manage the size of the files. The resource required to write logs to a 1MB file would be less than writting to a 10GB file, so manage your IIS logs appropriately. "

References:

https://mlichtenberg.wordpress.com/2011/09/19/catching-unhandled-exceptions-in-asp-net/

https://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging
http://www.codeproject.com/Articles/850062/Exception-handling-in-ASP-NET-MVC-methods-explaine?msg=5225761#xx5225761xx

http://stackoverflow.com/questions/2480006/what-is-the-difference-between-customerrors-and-httperrors
http://stackoverflow.com/questions/2640526/detailed-500-error-message-asp-iis-7-5

http://www.codeproject.com/Articles/155810/Back-to-the-Basics-Exception-Management-Design-Gui
kiquenet.com

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.