0

I have a question regarding static members and functions of non static classes.

I have a static member in my class that I use for authentication. Basically I call a static function from my web application and then inside I call a static function that assigns a value to that static member. Now my question is, will each call to a static function from my web application create a new reference to the object and assign a new value to the static member.

So basically I have this:

public class ClassA
{
     private static int UserId;

     private static AssignIdToUser(string token)
     {
         UserId = <int value depending on result of db query>;
     }

     public SendMessage(string token, string message, string toaddress)
     {
         AssignIdToUser(token);
         Message msg = new Message(); //This is just a sample of a class that is similar to the one I use
         msg.Message = message;
         msg.UserId = UserId;
         msg.ToAddress = toaddress;
         //add class to db and save
     }
}

Then in my web application I can do:

ClassA.SendMessage("userstoken", "This is a message", "0123456789");

Now if two users log on at the same time and the function gets called at the same time will the member UserId have the correct value for each user?

Basically is a instance of the object created for each request or is the same object used?

David Hall
  • 32,624
  • 10
  • 90
  • 127
Armand
  • 9,847
  • 9
  • 42
  • 75
  • Because a new instance of class is created for every user as the class is non static – Rashmi Kant Shrivastwa Feb 15 '12 at 11:38
  • 1
    @RashmiKantShrivastwa The line `ClassA.SendMessage` does not create an instance of `ClassA`, all it will do is initialize any static members / call static constructor on first call. So your comment is almost entirely incorrect. – Adam Houldsworth Feb 15 '12 at 11:40
  • 2
    The answers cover your main question (doing it this way is not safe) but it is also worth commenting on your last line. With static members there is no instance object created, so you can't even say that the 'same' object is used. Have a look at the MSDN documentation on this http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.80).aspx this is critical to understand when using static - very easy to shoot yourself in the foot otherwise. – David Hall Feb 15 '12 at 11:52

4 Answers4

4

An instance of the static member will exist for each AppDomain, unless you specify [ThreadStatic] in which case it will be per thread, but always per type (note, generics play on this point heavily!)

Static members are not a good choice for web apps because IIS recycles AppDomains regularly. You'd lose the static each time it recycled.

User actions are usually stored in Session state, I'd start here. Assuming ASP.NET:

Session State on MSDN

Application State on MSDN

Adam Houldsworth
  • 63,413
  • 11
  • 150
  • 187
  • 1
    .... and ThreadStatic can be dangerous in ASP.NET Apps: http://stackoverflow.com/questions/4791208/threadstaticattribute-in-asp-net – gsharp Feb 15 '12 at 11:42
  • @gsharp Static generally is dangerous as IIS recycles AppDomain/Processes at will. I preach avoidance, but thanks for the additional info. – Adam Houldsworth Feb 15 '12 at 11:44
  • 2
    @Armand You assume incorrectly. A static function will be called statically on the type - it has no knowledge of an instance, hence the `this` keyword is not allowed inside static methods nor can you access non-static members. If you need to hold per-user information, look into `Session` state, if you need to hold it for the entire app, look into `Application` state. – Adam Houldsworth Feb 15 '12 at 11:45
  • agree with you. I just wanted to make sure, that Armand doesn't want to implement a ThreadStatic solution. – gsharp Feb 15 '12 at 11:46
  • @AdamHouldsworth Thanks, I appreciate the clearing up of it all – Armand Feb 15 '12 at 12:00
1

The values in static fields are shared between requests. Use an instance field and create a new instance of your object every time, or pass in the UserId to the method.

Matti Virkkunen
  • 63,558
  • 9
  • 127
  • 159
1

No, a static member is shared across all instances so the userid would be an unpredictable value. It would be a better idea to have your assign function return the userid then youd have the correct value for each invocation.

ie.

var userId = AssignIdToUser(token);
....
msg.UserId = userId;
kaj
  • 5,133
  • 2
  • 21
  • 18
  • Will this then solve the issue of unpredictable user id's? Or what about changing the static member to a non-static member and then in each static function I create an instance of the object? – Armand Feb 15 '12 at 11:46
  • @Armand: You won't **need** the static member UserId any more. The function will return the value directly to the code that needs it. So there's no need to have a variable outside SendMessage to store the UserId. – kaj Feb 15 '12 at 11:53
  • @Armand: and no there won't be any further predictable behaviour that way – kaj Feb 15 '12 at 11:53
0

The functions you are using are not threadsave.

If you have two Objects one two differnt threads (T1 and T2) executing at the same time it may happen, that the first invokation of SendMessage() (for example at T1) gets interrupted right after AssignIdToUser(). If now T2 gets scheduled and completes one invokation of SendMessage() the SendMessage()-method in T1 will use the same user id as the SendMessage-method in T2.

You shouldn't use any static variables in this place. But you could use a static function like this, for example:

 private static int getUserIdForToken(String token) {
     ...
     return <int value depending on result of db query>;
 }
AlexS
  • 5,295
  • 3
  • 38
  • 54