C#静态成员

时间:2012-02-15 11:34:33

标签: c# .net oop web-applications

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

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

基本上我有这个:

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
     }
}

然后在我的网络应用程序中,我可以这样做:

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

现在,如果两个用户同时登录并同时调用该函数,那么成员UserId是否具有每个用户的正确值?

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

4 个答案:

答案 0 :(得分:4)

每个AppDomain都会存在静态成员的实例,除非您指定[ThreadStatic]在这种情况下它将是每个线程,但总是按 类型 (注意,仿制药在这一点上玩得很重!)

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

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

Session State on MSDN

Application State on MSDN

答案 1 :(得分:1)

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

答案 2 :(得分:1)

不,所有实例都共享一个静态成员,因此userid将是一个不可预测的值。让你的assign函数返回userid然后你有每个调用的正确值是一个更好的主意。

即。

var userId = AssignIdToUser(token);
....
msg.UserId = userId;

答案 3 :(得分:0)

您使用的功能不是线程。

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

您不应在此处使用任何静态变量。但是你可以使用这样的静态函数,例如:

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