views:

125

answers:

3

I am attempting to create a singleton service that is used to process incoming requests to an HttpHandler. At the moment the service is being instantiated on every request. I make a call to the static class that holds an instance of the service, implemented as a singleton as below:

 public static class ServerApplication {

static Service instance = null;
static readonly object padlock = new object();

/// <summary>
/// Service singleton.
/// </summary>
public static Service Service {
  get {
    lock (padlock) {
      if (instance == null) {
        instance = new Service();
      }
      return instance;
    }
  }
}

And access it using a call as below in the HttpHandler:

ServerApplication.Service.Process(request);

I have set a breakpoint on the instance = new Service(); line and with multiple requests the breakpoint is triggered per request.

My aim is a service that exists across requests as it loads and caches lots of data from files and databases that is reused with most requests.

Can anyone see what is going wrong?

+1  A: 

HTTP is designed to make several concurrent connections, I don't know that you'd want to break this, unless you make very few connections on page loads. That said, perhaps you could keep the HttpHandler in the Session?

lod3n
Making a HttoHandler a Singleton, is like trying to make a car float on the water... it just wasn't made to do that.
Chuck Conway
I am not making the http handler a singleton.
theringostarrs
+1  A: 

A couple of things:

  • If it's a multiprocessor box, technically, you should mark the shared service instance with the "volatile" keyword or use a call to MemoryBarrier (see http://blogs.msdn.com/brada/archive/2004/05/12/130935.aspx). You didn't specify architecture, so hard to say if this is really the issue, but better safe than sorry.
  • You should implement a double-check lock (eg, check for null both before and after acquiring the lock on "padlock"). This way you're doing a much cheaper comparison instead of acquiring a lock on all the subsequent reads.

That should cover you on the concurrency fronts. It's also possible (though less likely) that your AppDomain is being unloaded between requests (ie, you wrote a file inside the web directory causing ASP.NET to think your app is stale), which would cause the statics to be reset.

nitzmahone
I write to text and image files with in my server folder, would this cause the app pool reset? I was under the impression it was when you changed a .dll, or updated the web.config.
theringostarrs
It's supposed to be, but I've run into issues where it gets a little jumpy and whacks the app pool anyway. Implement the Application_End handler in global.asax and set a breakpoint if you suspect that's what's happening. You can then interrogate HttpContext to ask it why the app is shutting down.
nitzmahone
I've learned the hard way to write tempfiles, etc outside the virdir just to avoid stuff like this. :)
nitzmahone
A: 

Generally speaking, if you want a singleton - cannot see if its necessary i usually implement it this way: http://www.vikingworks.dk/page/Creating-a-Singleton-Pattern-i-C.aspx

H4mm3rHead