Static variables in asp.net? - asp.net

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?

Related

Can multiple requests affect users in one single IIS instance?

I'm having a problem on my application. It's an ASP.NET application set up on IIS 10.
Let's say one system page is accessible by 20 users. The page works perfectly (no logical error on coding) every action works and delivers the expected values requested by users.
The problem is, whenever someone requests let's say, the same method as another user at the same time (with different values), the application randomly throws an error to one of these users. We've checked for log errors and all of them are system index out of range errors, which never happened in our QA server.
I randomly thought about testing that exact scenario (adding different values with another user at the same time) and I saw it happen for the first time on the QA server. We've managed to reproduce the error multiple times.
While we don't discard the possibility that this could be another issue, did anyone else experience something like that?
The question is: Can IIS manage the same requests, multiple times at the same time within the same instance without any trouble? Does it run on multiple threads or something like that?
Thanks for taking time for answering this, if you need any info
Stick to your question
Yes IIS can handle very easily (more efficient as well)
As per your application concern without code I can't point out but you may consider few points
Is it happening for just one method or for all. If it happening for just one that means you are trying to use such a code that may used by another user
You are using such a array or list which is null or empty for other user. Like a user has First Name Followed by Last Name But other user don't fill last name and you are using that last name property
May be u r using HttpContext and trying to use same as for different users
May be You are using types which are not Thread safe
So these can be possible cases but without code we can't assume.
About your problem, for multiple requests from different user, iis will create a thread in the application pool for each request. For multiple requests from the same user, it will only run in one thread and affect only the user's instance. Unless the instance or resource is a shared resource and your code does not perform any lock operations.
IIS, including most web servers, use threads to process requests, so multiple requests will be executed in parallel unless you place a lock. A web server usually has a minimum and a maximum number of work programs. These work programs are adjusted according to the CPU or memory of the current hardware. If resources are exhausted, new requests will be queued until new resources are available.
So what you need to do may be to modify the application code to take multi-threading and synchronization into consideration.

Windows Azure. Get unique application instance ID

We use "Websites" in Windows Azure. I need to get unique application instance. I know about "RoleEnvironment.CurrentRoleInstance.Id" but as long as I know it works only for web roles. So I'm thinking about the following way to get unique application ID for each instance. I'm interested whether it's OK to use. Or am I missing something?
Once the application is started I generate some unique name (in the "Application_Start" method). For example, Guid.NewGuid().
Once it's done I store this unique value in some static variable.
When a second instance in started, steps 1 and 2 are repeated and some other new unique name is generated
This way I have unique names for each instance. Of course, once a site (or some instance) is restarted I'll get new absolutely unique values. But it's fine in our case.
Please let me know if you find any pitfalls in this solution
You could use the COMPUTERNAME or the WEBSITE_INSTANCE_ID environment variables instead.
In fact, you can browse the full list of environment variables at https://<yoursite>.scm.azurewebsites.net/Env
This should work, but of course the GUID will only be around for the lifetime of the w3wp process. So you would have unique names per w3wp process which would imply that you would have unique names for each instance.
If you wanted to use a more targeted unique name, you could experiment with the ARR affinity cookie. Azure Web app runs with a sticky session load balancer (when running with multiple instances) by default. It injects ARR affinity cookie in the HTTP response that helps in redirecting a user to the same instance with which it established the session at the first time.
You can also use the environment variables to uniquely identify the instance, i.e. Environment.ComputerName.

value of ASP.NET variables for different users

I'm using VS2010,C# to develop my ASP.NET web app, sometimes I need to declare public or even public static variable at start of my codebehind files, so that I can access them globally in the file and also they preserve their value between postbacks, everything works fine on my local server (as I'm the only person who runs the code). But I don't know exactly what happens when this page (and therefor its codebehind) are run by several web site visitors at the same time, I want my program to run the same for all users, but I think in this way something will cause problems, I can remember from my previous ASP.NET experience that using variable (public or public static) in codebehind can cause misunderstanding for different users of web site, for instance:
user A runs program, (public static int) my_int that had the value of -1 at startup has taken value of 100, and at this time user B runs the same page, so my_int is 100 and it will cause problems, also suppose that user A leaves the page while my_int has value of 100, then user B will visit the page my_int would be initially 100 (while that should be -1) so I think unexpected behaviors would occur
is it right? will this happen at all? if so, how can I prevent it? should I use session instead of variables? how can I have a better understanding about the whole situation
thanks friends
A simple rule - you need to choose storage as per the scope of data being stored. And for any mutable (read/write) shared state, you have worry about concurrent access (thread safety). For example, if a variable is a static then it would available through-out application (correctly speaking app-domain) but it also means you have ensure thread-safety while reading/writing the variable. Here are few tips
For per request scope, use local variables. No need for thread-safety (as only request thread would access it).
For per page scope (over repeated post-backs), use view-state. No need for thread-safety (as only request thread would access it).
For per user scope, use session state. A good thing about session state is that you don't have to worry about thread-safety (ASP.NET take care of that).
For application wide scope (strictly speaking app-domain wide scope), use application state or static variables. Application State offers lock/unlock API for thread-safety while for static variables, you have put your own locking mechanism. Static variables are good bet for application wide read-only data i.e. you initialize them at the start of application and then use the information whenever needed w/o locking because there are no writes.
For any scope larger than this, use database (or any other persistent data store). For database, transactions are used to ensure consistency.

ASP.NET: Application lifecycle, static variables

A class in my ASP.NET website needs to access a database table multiple times for every request. The database table should rarely change, if ever. Maybe a couple times a month.
In the static constructor of the class, the table is fetched from the DB and cached in a static local variable. Whenever the class needs to access the table, then, it just uses the cached, static version.
My question concerns the lifespan of this cached, static version of the table.
I understand that it's fetched the first time the class is instantiated or a static method in the class is used. But how often does this occur on the web server? What if the table changes and we want to reset this static version of the table?
Basically, I'm wondering, is this table fetched once and then only refetched each time I restart IIS? What, with regard to the site and IIS, will trigger this static class to reset, causing the static table to be refetched?
Rather than a static variable on a class, why not make add this to the 'Application' collection? It's lifetime is well understood (the life of the website) and can easily be recycled by touching web.config. Populate it in your Application_Start method of global.asax.
I'd recommend using the ASP.NET cache itself, rather than having variables for each particular cache item (a single table right now, but I'm sure there's room for growth); this way you can specify expiration, among other things, such as dependencies.
You can get information on the cache here, and more specifically, using the cache here.
To answer your question about the life-cycle, or expectancy of a local variable, see this link, which should do a better job of explaining the innards than I.
Basically, I'm wondering, is this
table fetched once and then only
refetched each time I restart IIS?
Yes, you've got that spot on. Essentially, restarting IIS will cause your static variable to be "refreshed". If you use a static variable to store this kind of thing (which may not be the best solution, but I'm trying to directly answer your question without getting sidetracked), I would advise you build some code into your data layer so that your static variable is updated each time the database table in question is written to. This will mean that you dont need to bounce the server each time you update it.
Its also worth remembering that static variables are shared across all client requests, this can often lead to some unpredictable multi-threading errors.

ASP.Net Session

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.

Resources