我有一个关于静态成员和非静态类函数的问题。
我的班级中有一个静态成员用于身份验证。基本上我从我的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是否具有每个用户的正确值?
基本上是为每个请求创建的对象的实例,还是使用的是同一个对象?
答案 0 :(得分:4)
每个AppDomain
都会存在静态成员的实例,除非您指定[ThreadStatic]
在这种情况下它将是每个线程,但总是按 类型 (注意,仿制药在这一点上玩得很重!)
静态成员不是Web应用程序的不错选择,因为IIS会定期回收AppDomains。每次回收都会失去静电。
用户操作通常存储在Session
状态,我从这里开始。假设ASP.NET:
答案 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>;
}