This is the continuation of my article Tips and Tricks of Exception Handling in .Net - Part 2
Fail Fast Method: There are situations where your application's state is very bad and no code should be executed further - not even finally block code and your application needs to be closed immediately. How you do this?
The answer is Environment's FailFast method. As the name suggests, this is a special method which causes your application to fail immediately. It also creates a dump and event viewer entry.
Fail Fast Method: There are situations where your application's state is very bad and no code should be executed further - not even finally block code and your application needs to be closed immediately. How you do this?
The answer is Environment's FailFast method. As the name suggests, this is a special method which causes your application to fail immediately. It also creates a dump and event viewer entry.
try { Environment.FailFast("Text to be logged"); } finally { Console.WriteLine("This finally block will not be executed."); }
Process.GetCurrentProcess().Kill() vs Environment.FailFast(""): The finally block will not be executed even if you use Process.GetCurrentProcess().Kill() and this also ends your application immediately, then how it differs from FailFast? well, the difference is - FailFast will create a dump and event viewer entry but killing the current process will not.
Note: The both should be used with extensive care. In real-world these are required very rarely.
Corrupted State Exceptions (CSE): These are the exceptions which cannot be catched. Behind the scene Environment's FailFast method throws one of these exceptions. Hence, it cannot be catched and your application ends with an unhandled exception.
Here is the explaination of CSE by Jffrey Richter's words:
Usually, CLR considers few exceptions thrown by native code as Corrupted State Exceptions, because they are usually the result of a bug in the CLR itself or in some native code for which the managed developer has no control over. Here is the list of native Win32 exceptions that are considered CSEs:
EXCEPTION_ACCESS_VIOLATION EXCEPTION_STACK_OVERFLOW EXCEPTION_ILLEGAL_INSTRUCTION EXCEPTION_IN_PAGE_ERROR EXCEPTION_INVALID_DISPOSITION EXCEPTION_NONCONTINUABLE_EXCEPTION EXCEPTION_PRIV_INSTRUCTION STATUS_UNWIND_CONSOLIDATE
By default, the CLR will not let managed code catch these exceptions and finally blocks will not execute. However, Individual managed methods can override the default and catch these exceptions by applying the System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute to the method. In addition, the method must have the System.Security. SecurityCriticalAttribute applied to it. You can also override the default for an entire process by setting the legacyCorruptedStateExceptionPolicy element in the application’s Extensible Markup Language (XML) configuration file to true. The CLR converts most of these to a System.Runtime.InteropServices.SEHException object except for EXCEPTION_ACCESS_VIOLATION, which is converted to a System.AccessViolationException object, and EXCEPTION_STACK_OVERFLOW, which is converted to a System.StackOverflowException object.
Note: Even with the attribute HandleProcessCorruptedStateExceptions, we cannot handle the following exceptions, for a given reason:
- StackOverflowException - As this is a hardware failure and there is no more stack available for further processing (Thanks Abel Braaksma for pointing this out).
- ExecutionEngineException - It occurs because of heap memory corruption and hence cannot be handled further (Reference).
Summery:
- Structured Exception Handling - This is the exception handling mechanism which is offered by Microsoft Windows and .Net Framework Exception Handling is built on the top of it.
- What can be thrown? - The CLR allows an instance of any type to be thrown. But CLS mandates to throw only the Exception derived objects. The C# compiler allows to throw only exception derived types.
- Throw different exception than the originally thrown one, when you want to maintain the meaning of a methods contract.
- Make sure to set original exception as inner exception when you throw a different exception.
- Constrained Execution Regions - Make sure that your catch or finally block will never throw an exception by making use of CER. You can use it by calling RuntimeHelpers's PrepareConstrainedRegions method and applying ReliabilityContract attribute wherever required.
- The C# language automatically emits try/finally blocks whenever you use the lock, using, and foreach statements.
- Call Environment's FailFast method when you want your application to be closed immediately and put a dump with event viewer entry.