views:

155

answers:

5

I have a .net application (c#) that goes something like this

public partial class _Default : System.Web.UI.Page
{
    #region initial variables setup

    private static exam theExam;

    #endregion


    protected void Page_Load(object sender, EventArgs e)
    {
       if(!IsPostBack)
       {
        string userid = Request.Querystring["user"].ToString();
           theExam = new exam(userid, "some values");
       }
    }
// rest of code.

Now my question is, if user 105 logs in an instance of exam theExam is created and assign to the static declaration on top. If user 204 then logs in from a different computer, does the static object at the top gets the value of 204 even on user's 105's computer?

+6  A: 

No, the static object is the same instance for everyone logged on. Also the object doesn't live on 105's computer but just on the web server ofcourse.

Sander Rijken
For clarification: Statics are unique to the app-domain, in which case that's the entire web-application. Note: If you use load balancing they're not unique across the two+ servers. So keep this in mind for horizontal scaling.
Aren
If you use the [ThreadStaticAttribute] each thread will have its own instance of that static variable.
Bear Monkey
Indeed, but the threads are reused for different requests, so it's not good enough. Using the Session is the best way for something like this.
Sander Rijken
Of course. The session is what should be used. Using static variables in ASP.NET is a bad idea. I was replying to Aren mainly commenting that statics aren't necessarily just unique to the app-domain.
Bear Monkey
+4  A: 

Short answer: yes, the static field is global to the AppDomain, so doing this for one user will step on the data for another user.

You probably want to look into using Session storage instead, which is scoped per-user, e.g.

var theExam = Session["exam"] as Exam;
flatline
+1 for AppDomain
James Westgate
+1  A: 

There is one "instance" of a static object per AppDomain. So the answer to your question is yes. Since you overwrite the variable when user 204 logs in, the same value will appear for user 105, too.

Some general advices

  • Avoid static fields wherever possible
  • Use the Session for storing temporary information in the context of a user's browsing session
    Session["exam"] = currentUser.Exam;
  • Use a Profile Provider for persisting information about each user between sessions.
Venemo
I think saying "avoid static fields wherever possible" is overdoing it a bit. I've seen people who are literally scared of using them because they don't understand how they work and somebody told them they might mess things up. There's nothing wrong with using them and make many things so much easier (helper methods, caching in memory). You just need to know how to use them correctly.
Matti Virkkunen
@Matti - A method is not a field. Nothing is wrong with helper methods. *You just need to know how to use them correctly* - Agreed! :)
Venemo
@Venemo: I've seen people who are afraid of the entire keyword `static` :I
Matti Virkkunen
@Matti - Me too, but more in the context of C/C++ than C#
Venemo
A: 

There's also a [ThreadStatic] attribute in .Net that will make one static instance per thread.

http://msdn.microsoft.com/en-us/library/system.threadstaticattribute(VS.71).aspx

Steven
It's good that you mention it, but in this case it would also be bad, as the threads are reused in the ASP.NET threadpool.
Sander Rijken
However, a thread is not dedicated for each user. Not even a single request is guaranteed to stay in the same thread from start to end. So, threadstatics is mostly (if not completely) useless in web applications.
Guffa
+4  A: 

Lifetime of static variables and user sessions are very different concepts. Static variables have a lifetime defined by the CLR and essentially boils down to the following 2 rules

  1. There is one storage location for a static variable per AppDomain
  2. Each unique instatiation of a generic type creates a different static variable.

I'm finding it hard to write the second rule without it being ambiguous as to unique. Essentially MyType<int> and MyType<string> each have different static variables. While MyType<int> and MyType<int> share the same one.

User's acess to a web server don't affect either of these.

If you want to have per user data then use the Session to store the data.

Session["examKey"] = theExam;
JaredPar
+1 for the explanation for Generic types.
Conrad Frix
I'm not sure if I'm doing this right but basicly what i did is exam newExam = new exam(value, value); Session["someKey"] = newExam, then I just cast Session["someKey"] like exam theExam = (exam) Session["someKey"] so I can get the objects... is this the correct way to do it?
Migs