I want to create a singleton that remains alive for the life of the app pool using HttpContent.Current.Cache.
Where would I create the class and how should it be implemented? I understand how to implement a singleton but am not too familiar with threading and httpcontent.current.cache.
Thanks!
It doesn't matter where to put the singleton code.
As soon as you access the instance and the type is initialized, it will remain in memory for the entire life of your ApplicationDomain. So use it as a normal class and the rest is done on first use.
Perhaps you are over-complicating the issue? i'm not sure why you need to use the cache. Could you not just add a file to the App_Code folder to house your class e.g "mSingleton.cs"
public sealed class mSingleton
{
static readonly mSingleton _instance = new mSingleton();
public int MyVal { get; set; }
public static mSingleton Instance
{
get { return _instance; }
}
private mSingleton()
{
// Initialize members, etc. here.
}
}
Then it is global to all your code and pages, maintains state until the app pool recycles or there is a app rebuild (i don't know if this causes the app to recycle as well - if it does then it suits your criteria anyway), doesn't need to be added to any cache, application or session variables.. no messy handling
You can do this on page_load in any aspx.cs file and refresh it to see the count go up each time to prove state is maintained:
mSingleton getMyObj = mSingleton.Instance;
getMyObj.MyVal++;
I'd not use the cache for this. I'd recommend a static class or singleton with static getInstance().
Related
I am storing some information in static dictionary which is defined in class inside WCF service component like below :
public class UserAuthenticator : IUserAuthentication
{
public static ConcurrentDictionary<UserInfo, ConcurrentDictionary<string, BookingDetails>>BookingDetailsDictionary = new ConcurrentDictionary<UserInfo, ConcurrentDictionary<string, BookingDetails>>(new UserEqualityComparer());
public static ConcurrentDictionary<string, Connector> connectorDictionary = new ConcurrentDictionary<string, Connector>();
public BookingDetails Authenticate(UserInfo userInfo, ServiceDetails serviceDetail, XmlElement requestData)
{
var bookDetails = new BookingDetails();
try
{
ConcurrentDictionary<string, BookingDetails> dicObject = null;
if (bookingDictionary.TryGetValue(userInfo, out dicObject))
{...}
else
{
// call Database and get value from database and fill db value in to static ConcurrentDictionary
}
}
}
}
Here I check static ConcurrentDictionary key if value in the not in dictionary then call database and fill value in the dictionary.
Expected output is first time invoke wcf service then call database and fill value in the ConcurrentDictionary and then after all the WCF service call read data from ConcurrentDictionary
Now, problems is sometimes I see that the static ConcurrentDictionary count are zeroed. And the strange part is the application pool is still active. no application pool is recycle still randomly it call database and sometime it take data from ConcurrentDictionary
This is really strange for me. I assume that static variable will hold its value until the application ends. But even the application pool did not recycle or IIS is not restarted, the static variable is zeroed.
What do you suggest? Is using ConcurrentDictionary variables a better choice?
Note : I have used castle windsor dependency injection in my wcf application and UserAuthenticator class is register with LifestyleTransient() like below
Component.For<IUserAuthentication, UserAuthenticator>().LifestyleTransient()
Please advice me the best solution
Thanks in advance
Finally I got solution of above problem
As I have used static ConcurrentDictionary in WCF project and also implemented web garden and static variables per process so its not working in another process some time with web gardern
Solution is as off now stopped wen garden and its working fine and in future will implement distributed cache like (Radis, NCache, etc) with web garden
Thanks to #mjwills and # Shantanu for valuable comments
I am creating an ASP.NET MVC web application. It has service classes to execute business logic and it access data through Entity Framework.
I want to change some business logic based on application variable. These variables are global variables and load from app config and don't change after the initial loading.
public class BroadcastService : IBroadcastService
{
private static readonly ILog Logger = LogProvider.GetCurrentLogger();
private readonly IUnitOfWork _worker;
private readonly IGlobalService _globalService;
public BroadcastService(IUnitOfWork worker, IGlobalService globalService)
{
_worker = worker;
_globalService = globalService;
}
public IEnumerable<ListItemModel> GetBroadcastGroups()
{
if(Global.EnableMultiTenant)
{
//load data for all tenants
}
else
{
//load data for current tenant only
}
return broadcastGroups ?? new List<ListItemModel>();
}
...
}
public static class Global
{
public static bool EnableMultiTenant{get;set;}
}
For example, EnableMultiTenant will hold application is running in multi-tenant mode or not.
My concerns are:
Is it ok to use a static global variable class to holds those values?
This application is hosting on Azure app service with load balancing. Is there any effect when running multi-instance and when app pool restarts?
To answer your question as to whether it is 'okay' to do this, I think that comes down to you.
I think the biggest thing to know is when that data is going to get refreshed. From experience I believe that static information gets stored in the application pool, so if it is restarted then the information will be refreshed.
Lifetime of ASP.NET Static Variable
Consider how many times you need that information, if you only need it once at startup, is it worth having it as a static. If you are getting that information a lot (and say for example it is stored in a database) then it may be sensible to store that in a cache somewhere such as a static member.
I think my only recommendation with static member variables is asp is keep them simple, booleans seem fine to me. Remember that users do share the same application meaning that static variables are global for all users. If you want a user specific variable then you want to use sessions cache.
Always remember the two hardest thing in programming
Naming things
Cache invalidation
Off by one errors
https://martinfowler.com/bliki/TwoHardThings.html
Even though this is a joke, it holds a lot of truth
Hope this helps
This is thread safe if you initialize these values once and then only read from them. It is also safe in the presence of multiple worker processes and restarts because the multiple processes don't share variables.
As an alternative consider creating an instance of a class holding your settings:
class MySettings {
bool IsEnabled;
}
Then you can use dependency injection to inject a singleton value of this class to your code. This makes it easier to tests and makes the code more uniform.
I have a web forms site that use NHibernate to connect to a MSSQL database.
I use the following class to create the SessionFactory and get the current session to use:
internal static class SessionManager
{
static readonly Configuration Configuration = new Configuration().Configure();
internal readonly static ISessionFactory SessionFactory = Configuration.BuildSessionFactory();
internal static ISession CurrentSession { get { if (!CurrentSessionContext.HasBind(SessionFactory))CurrentSessionContext.Bind(SessionFactory.OpenSession()); return SessionFactory.GetCurrentSession(); } }
}
And that is an example of how I use the previous one:
public abstract class Repository<TEntity>
{
protected internal ISession Session { get { return SessionManager.CurrentSession; } }
public IQueryable<TEntity> AllItems { get { return Session.Query<TEntity>(); } }
}
Everything works fine, although I believe I'm doing something really bad in terms of performance and scalability, but I can't see what.
Can anyone point me out what is and/or suggest a better way to handle this?
Thanks in advance!
I think the main issue in your code is that, when you put the Session object as a static field in a static class, you will have only one session for the whole process, what can bring you problems, like "a different object with the same identifier value was already associated with the session", for example.
What you could do is create another static method to allow you to close the session, but you would have to control when to close it (in a web environment, it could be in the end of every Request), or you could use some dependency injection framework like NInject or Castle Windsor to control the lifetime of the Session object.
Take a look at this:
(Yet another) nHibernate sessionmanager for ASP.NET (MVC)
Effective NHibernate Session management for web apps
We've run into a resource management problem that we've been struggling with for several weeks now and while we finally have a solution, it still seems weird to me.
We have a significant amount of interop code we've developed against a legacy system, which exposes a C API. One of the many peculiarities of this system is that (for reasons unknown), the "environment", which appears to be process-scoped must be initialized prior to the API being consumed. However, it can only be initialized once and must be "shutdown" once you're finished with it.
We were originally using a singleton pattern to accomplish this but as we're consuming this system inside an IIS hosted web service, our AppDomain will occasionally be recycled, leading to "orphaned" environments that leak memory. Since finalization and (apparently) even IIS-recycling is non-deterministic and hard to detect in all cases, we've switched to a disposal+ref counting pattern that seems to work well. However, doing reference counting manually feels weird and I'm sure there's a better approach.
Any thoughts on managing a static global disposable resource in an environment like this?
Here's the rough structure of the environment management:
public class FooEnvironment : IDisposable
{
private bool _disposed;
private static volatile int _referenceCount;
private static readonly object InitializationLock = new object();
public FooEnvironment()
{
lock(InitilizationLock)
{
if(_referenceCount == 0)
{
SafeNativeMethods.InitFoo();
_referenceCount++;
}
}
}
public void Dispose()
{
if(_disposed)
return;
lock(InitilizationLock)
{
_referenceCount--;
if(_referenceCount == 0)
{
SafeNativeMethods.TermFoo();
}
}
_disposed = true;
}
}
public class FooItem
{
public void DoSomething()
{
using(new FooEnvironment())
{
// environment is now initialized (count == 1)
NativeMethods.DoSomething();
// superfluous here but for our purposes...
using(new FooEnvironment())
{
// environment is initialized (count == 2)
NativeMethods.DoSomethingElse();
}
// environment is initialized (count == 1)
}
// environment is unloaded
}
}
I'm jumping in feet first here as there are a lot of unknowns about you particular code base, but I'm wondering is there is any mileage in a session based approach? You could have a (thread safe) session factory singleton that is responsible for ensuring only one environment is initialised and that environment is disposed appropriately by binding it to events on the ASP.NET AppDomain and/or similar. You would need to bake this session model into your API so that all client first established a session before making any calls. Apologies for the vagueness of this answer. If you can provide some example code perhaps I could give a more specific/detail answer.
One approach you might want to consider is to create an isolated AppDomain for your unmanaged component. In this way it won't be orphaned when an IIS-hosted AppDomain is recycled.
After looking at the .net on IIS7 application lifecycle:
http://msdn.microsoft.com/en-us/library/ms178473.aspx
For maximum performance, I want to find a way to get my code started as soon as the HttpContext object is created but before HttpApplication is. (it's easy to run code after the HttpApplication class is loaded but before any of it's event are triggered by using the contructor of an HTTP Module like this:
public class AuthModule : IHttpModule
{
public AuthModule()
{
HttpContext.Current.Response.Write("hello world");
HttpContext.Current.Response.End();
}
#region IHttpModule Members
public void Dispose()
{ }
public void Init(HttpApplication context)
{ }
#endregion
}
I know that i won't get access to the User object, but i won't need it.
You cannot ever be sure your code starts before the HttpApplication instance is created, since these instances may be reused.
Also, running code at this stage is beyond the scope of the pipeline. It should make you ask yourself whether it's really a sensible thing to do.
And what's this about performance? You really think the time to create an instance of HttpApplication is going to register in your performance?
Take a step back and reconsider.
Look at the life-cycle events on MSDN. You can consider using one of those events if you want something earlier than the normal page events.