Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type initializer (static constructor) exception handling

I'm writing a WCF service in C#. Initially my implementation had a static constructor to do some one-time initialization, but some of the initialization that is being done might (temporarily) fail.

It appears that static constructors are only called once, even if the first (failed) attempt threw an exception? Any subsequent attempts to instantiate my class will immediately fail with a TypeInitializationException without the code actually being executed.

The C# language specification states that a static constructor is called at most once, but basically this makes an exception in there an error that you cannot ever recover from, even if you catch it?

Am I missing something here? I suppose I should move anything remotely dangerous to the service's instance constructor and manually check whether or not the class initialization was already succesfully completed earlier?

like image 611
Thorarin Avatar asked Aug 25 '09 14:08

Thorarin


People also ask

What happens if a static constructor throws an exception?

It turns out that the static constructors are executed exactly once. If they throw an exception, it gets wrapped as an InnerException of the TypeInitializationException . Any attempts to use this class afterwards don't cause the constructor to execute again, but just make it throw the same exception once again.

What is a static constructor?

A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed only once. It is called automatically before the first instance is created or any static members are referenced.

Do static classes need constructors?

Can I Create The Constructor Of Static Class. You can not create an instance of class using new keyword. Rather, all functionality is exposed from the class level. So there is no need for a constructor in any Static class.


3 Answers

So you could wrap the critical parts in try/ catch and at least that means the type won't fail to initialize, but surely if the initialization code is that critical, then this behavior is actually good - the type is not usable in this uninitialized state.

The other option is to do it as a singleton - each time you try and get the Instance you can create the type correctly, until you are successful, even if it fails the first time.

You would still need some error handling on the caller in case Instance returns you null the first (or second etc.) time.

Edit: And if you don't want a singleton, then just have your instance constructor initialize the static parts

e.g.

private object _lock = new object()
private bool _initialized;

public T()
{
   lock(_lock)
   {
      if(!_initialized)
      {
         try
         {
           //Do static stuff here
         }
         catch(Exception ex_)
         {
           //Handle exception
         }
      } 
   }
}
like image 108
Gus Paul Avatar answered Oct 20 '22 07:10

Gus Paul


The lesson here is pretty simple: don't do anything in a static constructor that could reasonably fail.

like image 42
Barry Kelly Avatar answered Oct 20 '22 07:10

Barry Kelly


The workaround I used in the past is creating a Singleton. Make a static constructor fail if and only if the failure means the whole application can't run.

like image 24
Sklivvz Avatar answered Oct 20 '22 06:10

Sklivvz