Jeff and .NET

The .NET musings of Jeff Putz

Sponsors

News

My Sites

Archives

How do you get a true singleton in an ASP.NET app?

Something that has troubled me for awhile is that I can't quite figure out how to create a true singleton in an ASP.NET application. In other words, an object that lives in just once place, period. I thought that you could do this via an HttpModule, but when you debug you'll find that there is in fact more than one instance of the module.

I've also read that you can do it via global.asax in the Application_Start event, but that's less convenient because you can't configure it the same way you can an HttpModule by just commenting out the line in web.config.

I'm a little stumped.
 

Comments

Bill said:

You can always put an appsetting in and then check the value of the setting when you go to create the object in Application_Start.

# September 21, 2007 2:10 PM

Jeff said:

Actually, one thing I was thinking about was if I could simply surround my code in the HttpModule with a lock block, but I'm not sure what object I can put in there that is truly one of a kind. I thought about AppDomain.CurrentDoman, but I have no idea what kind of impact that would have.

If I could lock with the right object, I'm there for the purposes of what I'm trying to do.

# September 21, 2007 2:15 PM

The Other Steve said:

Just use the standard singleton pattern.  I've had to fix bugs where someone used a static variable inappropriately, so I know it works. :-)

Now if you are trying to do a singleton per request, that's different.

I guess maybe why do you think this is not working?

# September 21, 2007 2:20 PM

Will said:

I was under the assumption that creating a static var in global scope would work.  Maybe I'm mistaken...

# September 21, 2007 2:23 PM

Jeff said:

The way I thought it should work is to just create a static thread in an HttpModule, but ASP.NET can freely create more than one instance of the module. That means the two different threads can work on the same data. I guess my understanding of threading in this way is not ideal.

Per-request multi-threading I get. Doing it across an entire app, that I don't get. :)

# September 21, 2007 2:26 PM

Dave T. said:

Darn. I thought you were implying about a Singleton that lives across a Web Farm. Now that would be cool.

# September 21, 2007 2:27 PM

Joe said:

Here are a couple of implementations that I have found to work:

www.yoda.arachsys.com/.../singleton.html

# September 21, 2007 3:08 PM

JV said:

Implementing a singleton inside an ASP.NET application is nothing different from a normal application. However if you are like Dave T. says are implying to make it also working on a webfarm, then I indeed think that is a very nice challenge :)

# September 21, 2007 3:37 PM

AndrewSeven said:

Follow the Yoda link, fully nested.

For the webfarm you would probably be better off to use a service that lives on one machine ;)

# September 21, 2007 4:24 PM

Tyler Jensen said:

Jeff, the web garden will kill you every time, not to mention the idle timeout. See the application pool properties (msdn2.microsoft.com/.../Aa720391(VS.71).aspx) and you'll see that the very things that make IIS 6 so scalable, also make it very tough to maintain a true singleton. You have two choices. Turn off the scalability features by going down to one worker process and a number of other items, or use an independent application such as a windows service and then remote to your singletons. It's not pretty, but it's the price you pay for scalability.

# September 21, 2007 4:58 PM

Rick Strahl said:

Jeff, what are you actually trying to do? If you need a singleton that is local to the AppDomain a static variable anywhere should work. I tend to use a global App object from which any statics hang off of. (ie.  App.SingleInstance, App.Configuration etc.). You can also define these on HttpApplication as long as you make sure they the properties/fields are static.

# September 24, 2007 2:38 AM

Paul D. Murphy said:

Hmm... Some people made comments here that are just flat wrong.

IIS can & will create multiple worker processes. If you are running in a web garden mode IIS will create a worker process for each core in the system. IIS will also recycle processes on a single core machine; i.e. spin up a new process and process new requests on it while shutting down an old process that is done processing requests.

The ASP.NET worker process is a process just like any other process. So if you wrote a windows form application and ran two copies of it. Each AppDomain in that process, each static, everything is completely isolated from the other instance of your application. ASP.NET worker processes are no difference.

This means that if you want to share absolute consistent state across an ASP.NET application you *have* to implement that state server as a windows services that loads prior to the WWW service loading. And you *have* to talk to that state server through a mechanism like System.Remoting.Channels.Ipc (inter process communication remoting stack)

Most of us are lazy and just use a SQL Server database. If you need to use rich objects try MSMQ or the Session State service.

hth,

Paul

# October 3, 2007 3:48 PM

Mike Z. said:

It's even worse than that - ASP.NET can create multiple Application Pools within one worker process - and yes, they'll have separate set of static fields each. I stumbled across this problem and found no workaround which would not cripple efficiency and robustness. The "solution" was to use an external cache process which stored some objects. It obviously worked only with serializable objects (pieces of data, actually); if you need a fully functional, mutable object than it's even more of a challenge.

# April 28, 2011 10:01 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)