Showing posts with label Widows Service. Show all posts
Showing posts with label Widows Service. Show all posts

12 November 2016

Effect of exceptions while initializing the static members

Recently I encountered an error saying The type initializer for class threw an exception from a .NET windows service. The error was thrown while accessing any members/methods of a class. The error kept happening until the .NET Windows service was restarted.

After digging deeper into application error logs and analyzing the code in depth, I learnt the below:

  1. The offending class had static variables. One of the static variables was getting initialized by invoking DB repository method to get configured value.

    private static decimal minInsurancePremuimAmount = InsuranceConfigRepository.GetMinPremuimAmount();
  2. The database repository method was throwing exception when failed to fetch the data from Database Server in case of any transient error,etc.

    try
    {
    }
    catch(Exception ex)
    {
      // Log and throw the exception
      throw ex;
    }
  3. When the offending class was first accessed, .NET framework tried to initialize the static variables. When it tried to initialize the minInsurancePremuimAmount, it resulted in a SQLException because Database server was not accessible at that time.
  4. So .NET framework could not complete the class initialization logic. Hence application was giving the error until it restarted.

    The type initializer threw an exception.

What was the fix?

  1. So taking clue from the issue, code changed to ensure static members initialization logic will never throw the exception up the call stack. In case of any errors happened during the static members initialization, such Exceptions just eaten and logged for DEBUG purposes.
  2. In the offending class, the internal logic was modified.

    Before accessing such static members, the members were NULL checked. If they were still NULL, the code was added to initialize the variable.

    This way even if there is an exception, only the current method invocation would fail, but not any future method invocations will result in the error "type initializer threw an exception".

11 June 2016

why and when windows service went down

If you have worked on developing Windows Service application, you might have thought about, is there any better way to know when and why a service went down unexpectedly. If that is your case, continue reading. This blog post aims to discuss one of the way, in which you can catch why and when windows service went down.

Whenever you start a .NET application, it runs in an AppDomain. You are free to create a new AppDomain depending on the need for your application. Windows service built on .NET(System.ServiceProcess.ServiceBase) also runs in an AppDomain. All the assemblies loading and unloading happens with a given AppDomain.

AppDomain object exposes an event called "UnhandledException". This event will be fired whenever there is an exception which is not handled in your application code.

One of the main reason why windows service unexpectedly goes down is because of an Exception which is not handled. If exceptions are not handled, then they traverse go up the stack trace and kill the process. When that happens, the current AppDomain event get notified before application goes down.

So, AppDomain's UnhandledException event can be used to get notified of any such unhandled exception.

Steps to get notified via AppDoman UnhandledException event

FIRST, subscribe to the UnhandledException event inside the Windows service Startup code. Do this as early as possible, so that you will also get notified of any exceptions happened even during service startup.

static void CurrentDomain_UnhandledException
(object sender, UnhandledExceptionEventArgs e)
{
try
  {
    string errorType = e.IsTerminating ? 
    "ServiceShutDownError" : "UnhandledExceptionError";
    Exception exception = e.ExceptionObject as Exception;
    if (exception == null)
    {
     Exception comException = 
         new Exception(e.ExceptionObject.ToString());
     // This is com Exception. 
     // Invoke your PRODUCTION support team alert
    }
    else
    {
     // log exception
     // Invoke your PRODUCTION support team alert  
    }
  }
   catch
  {
    // do nothing. don't want to intervene 
    // in normal UnhandledException event flow
   }
}

The UnhandledExceptionEventArgs object has two properties.

  1. ExceptionObject. This give details about unhandled error happened in the application appdomain which caused this event to fire.
  2. IsTerminating. Indicates whether the common language runtime is terminating. If true, the windows service will shut down.

Caveats of this approach: Doesn't catch StackOverFlowExeption

Ran small console application to see whether UnhandledException event will be fired in case of OutOfMemoryException or StackOverFlowExeption.

  • In case of OutOfMemoryException, the event UnhandledException is fired.
  • In case of the StackOverFlowExeption, the event UnhandledException is not fired.