关于.net:C#静态成员

C# Static members

我有一个关于非静态类的静态成员和函数的问题。

我的类中有一个用于身份验证的静态成员。基本上,我从Web应用程序调用一个静态函数,然后在内部调用一个为静态成员赋值的静态函数。现在我的问题是,每次从Web应用程序调用静态函数是否都会创建一个对对象的新引用,并为静态成员分配一个新值。

所以基本上我有:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
     }
}

然后,在我的Web应用程序中,我可以执行以下操作:

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

现在,如果两个用户同时登录,同时调用函数,那么成员userid对每个用户都有正确的值吗?

基本上是为每个请求创建的对象实例,还是使用相同的对象?


静态成员的一个实例将存在于每个AppDomain中,除非您指定[ThreadStatic],在这种情况下,它将是每个线程,但始终是每个类型(注意,泛型在这一点上发挥了很大作用!)

静态成员不是Web应用的好选择,因为IIS定期回收AppDomain。每次回收都会失去静电。

用户操作通常存储在Session状态,我将从这里开始。假设ASP.NET:

msdn上的会话状态

msdn上的应用程序状态


不,静态成员在所有实例之间共享,因此用户ID将是不可预测的值。最好让assign函数返回userid,然后为每次调用提供正确的值。

IE.

1
2
3
var userId = AssignIdToUser(token);
....
msg.UserId = userId;


静态字段中的值在请求之间共享。使用实例字段并每次创建对象的新实例,或者将用户ID传递给方法。


您使用的函数不是threadsave。

如果有两个对象,一个两个不同的线程(T1和T2)可能同时执行,那么sendmessage()的第一次调用(例如在T1)会在assignidToUser()之后立即中断。如果现在t2被调度并完成对sendmessage()的一次调用,则t1中的sendmessage()-方法将使用与t2中的sendmessage方法相同的用户ID。

在这个地方不应该使用任何静态变量。但是您可以使用这样的静态函数,例如:

1
2
3
4
 private static int getUserIdForToken(String token) {
     ...
     return <int value depending on result of db query>;
 }