When i need to cache something in my application, i used to choose Web.Caching.Cache. But i ran into some legacy code that using HttpApplicationState instead.
Since Web.Caching.Cache is more powerful and flexible (seems MUCH more), is there a situation that better to use HttpApplicationState??
I will be very appreciate if you can show me some examples :-)
Both HttpApplicationState and Web.Caching.Cache can be used to store information that can be globally accessible throughout an ASP.Net application. However, they have very different uses.
HttpApplicationState is used to store application data that typically does not change. It is typically populated in Application_Start in Global.asax, when the application is starting. I personally have not used it much, but I believe it is typically used to store small pieces of application configuration that are global to all users of an application and which either do not change or change very infrequently. Something put into Application state will remain there indefinitely, until the app recycles. But when it recycles and restarts again, Application_Start will execute again and re-populate it.
It is important to note that HttpApplicationState is a singleton and is not thread safe. So when you make changes to it, you must lock and unlock the Application object via calls to Application.Lock() and Application.UnLock(). Read more
There are actually three different ways you can cache ASP.Net content: Page level, partial page, and data. I am going to talk about data caching, since I think that is most relevant to your question. The ASP.Net cache is used to store large quantities of application data that would be expensive to retrieve from a data store for every request. The key differences between HttpApplicationState and Cache are 1) Cache data is designed to expire and be purged from memory by a variety of triggers or conditions (time, other cache dependencies, etc), whereas HttpApplicationState will be there forever until the app recycles, and 2) Cache data can be purged from memory if a server is experiencing severe memory pressure, and you thus can never count on it being there and must always test to see if it is present, whereas HttpApplicationState will always be there.
Caching is used to store data closer to the application that does not need to be pulled from a database on every request. Caching is designed to store very large quantities of data, and an intelligent caching architecture can have an enormous positive impact on performance.
In Web application, I am using static variable, when more than one user accessing the same page where static variables declare, it could be conflict variables?, for example i am storing the session value in static variable, if the two employee are accessing the same page at a time it could wrong process na?.
Yes, there can be conflicts. You can end up with a lot of unexpected behaviors. Avoid them as you may have concurrency issues.
Yes conflicts will likely occur, the state of the variable is shared across the entire app domain.
A static variable has only one value for each appDomain. It means the same will be shared by all the request in the application . This may lead to conflicts . So never user static variable until and unless you are very sure about the behavior , use session instead.
Yes, that's why you should be VERY careful when you use static variables in a web app. You will run in concurrency issues as more than one thread servicing a request can modify the value of the variable.Static Variables Scope is Application Level. If you store some thing in it, then its a wrong thing. If one user saves the data, Same time another user accessed the same page then he will also get the same data. So try to store the values in Sessions.
While this works in single-user environment, What happens in a multi-user environment, if there are 2 users simultaneously logged in from two computers, User 1 sets the value as 200, then User 2 sets the value as 400. after that user 1 invokes the Get Value button. What will he see as the value?
In order to improve speed of chat application, I am remembering last message id in static variable (actually, Dictionary).
Howeever, it seems that every thread has own copy, because users do not get updated on production (single server environment).
private static Dictionary<long, MemoryChatRoom> _chatRooms = new Dictionary<long, MemoryChatRoom>();
No treadstaticattribute used...
What is fast way to share few ints across all application processes?
update
I know that web must be stateless. However, for every rule there is an exception. Currently all data stroed in ms sql, and in this particular case some piece of shared memory wil increase performance dramatically and allow to avoid sql requests for nothing.
I did not used static for years, so I even missed moment when it started to be multiple instances in same application.
So, question is what is simplest way to share memory objects between processes? For now, my workaround is remoting, but there is a lot of extra code and I am not 100% sure in stability of this approach.
I'm assuming you're new to web programming. One of the key differences in a web application to a regular console or Windows forms application is that it is stateless. This means that every page request is basically initialised from scratch. You're using the database to maintain state, but as you're discovering this is fairly slow. Fortunately you have other options.
If you want to remember something frequently accessed on a per-user basis (say, their username) then you could use session. I recommend reading up on session state here. Be careful, however, not to abuse the session object -- since each user has his or her own copy of session, it can easily use a lot of RAM and cause you more performance problems than your database ever was.
If you want to cache information that's relevant across all users of your apps, ASP.NET provides a framework for data caching. The simplest way to use this is like a dictionary, eg:
Cache["item"] = "Some cached data";
I recommend reading in detail about the various options for caching in ASP.NET here.
Overall, though, I recommend you do NOT bother with caching until you are more comfortable with web programming. As with any type of globally shared data, it can cause unpredictable issues which are difficult to diagnosed if misused.
So far, there is no easy way to comminucate between processes. (And maybe this is good based on isolation, scaling). For example, this is mentioned explicitely here: ASP.Net static objects
When you really need web application/service to remember some state in memory, and NOT IN DATABASE you have following options:
You can Max Processes count = 1. Require to move this piece of code to seperate web application. In case you make it separate subdomain you will have Cross Site Scripting issues when accesing this from JS.
Remoting/WCF - You can host critical data in remoting applcation, and access it from web application.
Store data in every process and syncronize changes via memcached. Memcached doesn't have actual data, because it took long tim eto transfer it. Only last changed date per each collection.
With #3 I am able to achieve more than 100 pages per second from single server.
need ask you about some help.
I have web app running in Net 2.0.
I wanna ask what storage (cache, session, file) I should use for my objects as they have different scope of using. Can be divide into several groups:
1) objects related directly to visitor (e.g. details about visitor that are received after authentication)
2) objects that are used for every visitor, so its scope of application (some init data, common data)
Most of these objects get data from web service, which is expensive.
So what's my best choices considering speed, memory, accessibility and what else I should look out.
Any help most welcome. Thanks, X.
Objects related directly to the visitor should be stored in Session although excessive use of Session and many users can lead to scalability issues.
Objects that are shared for every visitory should be stored in Cache so they will go out of scope if they aren't accessed often so that memory can be reclaimed (not to mention the added incentive of dependencies). In scenarios where you know an object must be accessible immediately no matter how much time has passed between the last time it was accessed, then you should store that object in Application.
Item 1 - Session would most likely be the best as it is per user, however, be sure to limit the number of items there as there are scaling issues, and considerations if in a web farm.
Item 2 - Depending on what you need, this would be a cache or application level item that you want to add, depending on need for expiration, etc. The key difference is cache has expiration and usage items that can remove it, application is for things that always stay there.
Overall, in a web application I strongly recommend AGAINST files as then you have to worry about thread saftey.
Objects relative per visitor should be stored in Session. This is unique per visitor, but tends to be frequently flushed, this also scales poorly when you move to a multiple server environment.
Objects relative to the application as a whole should be stored in the ASP.NET Cache.
I am wanting to store the "state" of some actions the user is performing in a series of different ASP.Net webforms. What are my choices for persisting state, and what are the pros/cons of each solution?
I have been using Session objects, and using some helper methods to strongly type the objects:
public static Account GetCurrentAccount(HttpSessionState session)
{
return (Account)session[ACCOUNT];
}
public static void SetCurrentAccount(Account obj, HttpSessionState session)
{
session[ACCOUNT] = obj;
}
I have been told by numerous sources that "Session is evil", so that is really the root cause of this question. I want to know what you think "best practice", and why.
There is nothing inherently evil with session state.
There are a couple of things to keep in mind that might bite you though:
If the user presses the browser back button you go back to the previous page but your session state is not reverted. So your CurrentAccount might not be what it originally was on the page.
ASP.NET processes can get recycled by IIS. When that happens you next request will start a new process. If you are using in process session state, the default, it will be gone :-(
Session can also timeout with the same result if the user isn't active for some time. This defaults to 20 minutes so a nice lunch will do it.
Using out of process session state requires all objects stored in session state to be serializable.
If the user opens a second browser window he will expect to have a second and distinct application but the session state is most likely going to be shared between to two. So changing the CurrentAccount in one browser window will do the same in the other.
Your two choices for temporarily storing form data are, first, to store each form's information in session state variable(s) and, second, to pass the form information along using URL parameters. Using Cookies as a potential third option is simply not workable for the simple reason that many of your visitors are likely to have cookies turned off (this doesn't affect session cookies, however). Also, I am assuming by the nature of your question that you do not want to store this information in a database table until it is fully committed.
Using Session variable(s) is the classic solution to this problem but it does suffer from a few drawbacks. Among these are (1) large amounts of data can use up server RAM if you are using inproc session management, (2) sharing session variables across multiple servers in a server farm requires additional considerations, and (3) a professionally-designed app must guard against session expiration (don't just cast a session variable and use it - if the session has expired the cast will throw an error). However, for the vast majority of applications, session variables are unquestionably the way to go.
The alternative is to pass each form's information along in the URL. The primary problem with this approach is that you'll have to be extremely careful about "passing along" information. For example, if you are collecting information in four pages, you would need to collect information in the first, pass it in the URL to the second page where you must store it in that page's viewstate. Then, when calling the third page, you'll collect form data from the second page plus the viewstate variables and encode both in the URL, etc. If you have five or more pages or if the visitor will be jumping around the site, you'll have a real mess on your hands. Keep in mind also that all information will need to A) be serialized to a URL-safe string and B) encoded in such a manner as to prevent simple URL-based hacks (e.g. if you put the price in clear-text and pass it along, someone could change the price). Note that you can reduce some of these problems by creating a kind of "session manager" and have it manage the URL strings for you but you would still have to be extremely sensitive to the possibility that any given link could blow away someone's entire session if it isn't managed properly.
In the end, I use URL variables only for passing along very limited data from one page to the next (e.g. an item's ID as encoded in a link to that item).
Let us assume, then, that you would indeed manage a user's data using the built-in Sessions capability. Why would someone tell you that "Session is evil"? Well, in addition to the memory load, server-farm, and expiration considerations presented above, the primary critique of Session variables that they are, effectively, untyped variables.
Fortunately, prudent use of Session variables can avoid memory problems (big items should be kept in the database anyhow) and if you are running a site large enough to need a server farm, there are plenty of mechanisms available for sharing state built in to ASP.NET (hint: you will not use inproc storage).
To avoid essentially all of the rest of Session's drawbacks, I recommend that implement an object to hold your session data as well as some simple Session object management capabilities. Then build these into a descendent of the Page class and use this descendent Page class for all of your pages. It is then a simple matter to access your Session data via the page class as a set of strongly-typed values. Note that your Object's fields will give you a way to access each of your "session variables" in a strongly typed manner (e.g. one field per variable).
Let me know if this is a straightforward task for you or if you'd like some sample code!
As far as I know, Session is the intended way of storing this information. Please keep in mind that session state generally is stored in the process by default. If you have multiple web servers, or if there is an IIS reboot, you lose session state. This can be fixed by using a ASP.NET State Service, or even an SQL database to store sessions. This ensures people get their session back, even if they are rerouted to a different web server, or in case of a recycle of the worker process.
One of the reasons for its sinister reputation is that hurried developers overuse it with string literals in UI code (rather than a helper class like yours) as the item keys, and end up with a big bag of untestable promiscuous state. Some sort of wrapper is an entry-level requirement for non-evil session use.
As for "Session being evil" ... if you were developing in classic ASP I would have to agree, but ASP.NET/IIS does a much better job.
The real question is what is the best way to maintain state. In our case, when it comes to the current logged in user, we store that object in Session, as we are constantly referring to it for their name, email address, authorization and so forth.
Other little tidbits of information that doesn't need any long-term persistence we use a combination of cookies and viewstate.
When you want to store information that can be accessed globally in your web application, a way of doing this is the ThreadStatic attribute. This turns a static member of a Class into a member that is shared by the current thread, but not other threads. The advantage of ThreadStatic is that you don't have to have a web context available. For instance, if you have a back end that does not reference System.Web, but want to share information there as well, you can set the user's id at the beginning of every request in the ThreadStatic property, and reference it in your dependency without the need of having access to the Session object.
Because it is static but only to a single thread, we ensure that other simultaneous visitors don't get our session. This works, as long as you ensure that the property is reset for every request. This makes it an ideal companion to cookies.
I think using Session object is OK in this case, but you should remember Session can expire if there is no browser activity for long time (HttpSessionState.Timeout property determines in how many minutes session-state provider terminates the session), so it's better to check for value existence before return:
public static Account GetCurrentAccount(HttpSessionState session)
{
if (Session[ACCOUNT]!=null)
return (Account)Session[ACCOUNT];
else
throw new Exception("Can't get current account. Session expired.");
}
http://www.tigraine.at/2008/07/17/session-handling-in-aspnet/
hope this helps.
Short term information, that only needs to live until the next request, can also be stored in the ViewState. This means that objects are serialized and stored in the page sent to the browser, which is then posted back to the server on a click event or similar. Then the ViewState is decoded and turned into objects again, ready to be retrieved.
Sessions are not evil, they serve an important function in ASP.NET application, serving data that must be shared between multiple pages during a user's "session". There are some suggestions, I would say to use SQL Session management when ever possible, and make certain that the objects you are using in your session collection are "serializable". The best practices would be to use the session object when you absolutely need to share state information across pages, and don't use it when you don't need to. The information is not going to be available client side, A session key is kept either in a cookie, or through the query string, or using other methods depending on how it is configured, and then the session objects are available in the database table (unless you use InProc, in which case your sessions will have the chance of being blown away during a reload of the site, or will be rendered almost useless in most clustered environments).
I think the "evil" comes from over-using the session. If you just stick anything and everything in it (like using global variables for everything) you will end up having poor performance and just a mess.
Anything you put in the session object stays there for the duration of the session unless it is cleaned up. Poor management of memory stored using inproc and stateserver will force you to scale out earlier than necessary. Store only an ID for the session/user in the session and load what is needed into the cache object on demand using a helper class. That way you can fine tune it's lifetime according to how often that data us used. The next version of asp.net may have a distributed cache(rumor).
Session as evil: Not in ASP.NET, properly configured. Yes, it's ideal to be as stateless as possible, but the reality is that you can't get there from here. You can, however, make Session behave in ways that lessen its impact -- Notably StateServer or database sessions.