Static variables in .net web api server [closed]

Welcome to Programming Tutorial official website. Today - we are going to cover how to solve / find the solution of this error Static variables in .net web api server [closed] on this date .

I have a web api server which basically responds to 2 requests: stop and start.

On start it does several things, for example, initializing timers that perform a method every X seconds, and on stop it just stops the timers.

In order to achieve that, I created a singleton class which handles the logic of the operations. (It needs to be singleton so the timers and more variables will exist only once for all the requests).

Server is running fine, but recently I got a AccessViolationException while accessing Globalconfiguration.AppSettings in order to retrieve a value from my webconfig file.

I found out by looking at my logs that the singleton class finalizer was called, even though I didn’t restart the server.

The finalizer calls a method which I regularly use and works fine in other scenarios, and this method uses the GlobalConfiguration class which threw the exception.

I tried to find the cause for this without success.

So basically there are two bugs here:
1. Why was the finalizer called out of the blue? The server could run for a week.
2. The AccessViolationException.

Perhaps the bugs are related? If my application memory was somehow cleaned would it cause the finalizer to be called and an exception accessing the GlobalConfiguration? Just a theory….

Or perhaps maybe I don’t handle the singleton properly? But, after reading about static variables in c# web servers I see that they should exist while the application exist, and as such the bug might not be related with handling the singleton. I do handle it OK – the singleton has a private static field which holds the actual instance and the initialization occurs via locking and double checking to prevent multiple threads creating the singleton.

Is my approach OK? Do you see any possible bug that I didnt expect in this behavior, or do you know of any behavior of the .net framework that could cause my static singleton to be destroyed?

Answer

For your first question as to why the finalizer was called the obvious explanation is that it didn’t have any active GC roots, which caused the GC to place it on the finialization queue. As to why the GC didn’t find an active root to your object there are two possibilities:

  1. You have a bug in your code and are not holding onto a reference to the singleton
  2. Your IIS application pool is being recycled (I’m assuming you’re hosting the app in IIS)

In its default configuration IIS automatically restarts each application pool every 1740 minutes (29 hours) which in turn causes the current app domain for your application to be unloaded. In .net static variables exist per app domain which means that when the app domain is unloaded there are no longer any active GC roots to the singleton, which in turn means that the singleton is eligible for garbage collection and by extension finalization.

With regards to the AVE you’re getting you need to remember that when your finalizer is executed everything you know is wrong. By the time your finalizer is executed the GlobalConfiguration object may have also been GC’d/finalized and whatever handle it had to the web.config may have been destroyed.

It’s also important to note that by default when IIS recycles your application pool it waits for the next HTTP request before it actually recreates the application pool. This is good from a resource utilization perspective as it means that if your application is not getting any requests it will not be loaded into memory, however in your case it also means that none of your timers will exist until your app receives an HTTP request.

In terms of solving this problem you have a couple of options:

  1. Disable IIS’s automatic restart. This solves your immediate issue however it raises the question of what happens if the server gets restarted for some other reason. Does your application have some way of persisting state (e.g. in a database) so that if it was previously started it will continue when it comes online?

    If so, you would also want to enable auto-start and pre-load for your application so that IIS automatically loads your application without an external HTTP request needing to be made. See this blog post for more details.

  2. Host outside of IIS. IIS is primarily designed for hosting websites rather than background services so rather than fighting against it you could simply switch to using a Windows service to host your application. Using Owin you can even host your existing Web API within the service so you should need to make minimal code changes.