ASP.NET 2.0 中的静态类变量行为?
如果我将此类定义为 ASP.NET 2.0 中应用程序的一部分:(
public class Foo
{
private static int _seed = 100;
private static object myLock = new object();
public Foo()
{
lock (myLock)
{
this.MyInt = _seed;
_seed++;
}
}
public int MyInt {get; set;}
}
编辑:更新以考虑答案所指出的线程安全问题)
该静态成员将如何表现?它会从 100 开始并为每个会话单独递增,还是会为每次页面刷新单独递增,还是全局...?
注意:我问这个问题是因为我第一次在 ASP.NET 应用程序中使用类来建模数据,并且我已经发现 C# 的按引用性质似乎被 ViewState 序列化忽略,所以我想知道我还能期待什么其他奇怪的事情。例如,如果我定义了这个类(假设 Bar
是另一个类):
public class OtherFoo
{
public List<Bar> Bars {get; set;}
}
并且我在我的页面上执行此操作:
OtherFoo _myFoo = new OtherFoo();
//Code here to instantiate the list member and add some instances of Bar
Bar b = _myFoo.Bars[0];
ViewState["myFoo"] = _myFoo; //Assume both are [Serializable]
ViewState["myBar"] = b;
当我在下一次回发时从 ViewState 中获取这些内容时,b 和
_myFoo.Bars[0]
不再是同一个对象。
If I've got this class defined as part of an app in ASP.NET 2.0:
public class Foo
{
private static int _seed = 100;
private static object myLock = new object();
public Foo()
{
lock (myLock)
{
this.MyInt = _seed;
_seed++;
}
}
public int MyInt {get; set;}
}
(Edit: updated to account for thread safety concerns as pointed out by answers)
How will that static member behave? Will it start at 100 and increment separately for every session, or will it increment separately for every page refresh, or is it global...?
Note: I'm asking this because I'm using classes to model data for the first time in my ASP.NET app, and I've already discovered that C#'s by-reference nature appears to be ignored by ViewState serialization, so I want to know what other weirdness I can expect. For example, if I have this class defined (assume Bar
is another class):
public class OtherFoo
{
public List<Bar> Bars {get; set;}
}
and I do this on my page:
OtherFoo _myFoo = new OtherFoo();
//Code here to instantiate the list member and add some instances of Bar
Bar b = _myFoo.Bars[0];
ViewState["myFoo"] = _myFoo; //Assume both are [Serializable]
ViewState["myBar"] = b;
When I get those out of ViewState on the next postback, b
and _myFoo.Bars[0]
are no longer the same object.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
ASP.NET 并不神奇。它不会神奇地将 C# 编程语言(或任何其他语言)转变为能够感知 Web 开发(会话、请求等)的语言。
您的代码的行为将与在任何其他类型的应用程序中完全相同,此外它可以由多个线程同时调用(因此使用“++”并不安全)。
再说一次,没有魔法。就像所有其他应用程序一样,静态的生命周期仅限于加载包含静态的类型的 AppDomain 的生命周期。
ASP.NET 应用程序中的 AppDomain 是在第一次访问应用程序时创建的(除非 IIS 设置强制其预先启动),并且仅在特定时间结束,例如当
bin
文件夹被更改,或者web.config
被更改,或者当 IIS 设置表明 AppPool 需要回收时。ASP.NET is not magic. It doesn't magically turn the C# programming language (or any other language) into a language that is aware of web development (sessions, requests, etc).
Your code will behave exactly as it would in any other kind of application, with the addition that it can be called by multiple threads at the same time (so that using "++" is not safe).
Again, there is no magic. Just like every other application, the lifetime of a static is restricted to the lifetime of the AppDomain in which the type containing the static is loaded.
An AppDomain in an ASP.NET application is created the first time the application is accessed (unless the IIS settings force it to pre-start), and only ends at certain times, like when an assembly in the
bin
folder is changed, or theweb.config
is changed, or when the IIS settings say that the AppPool needs to be recycled.每次调用构造函数时都会增加种子。请注意,这可能发生在多个线程中,因此最好使其线程安全。
反序列化将导致调用(默认)构造函数。如果将其序列化为 ViewState,则 ASP.NET 将在回发时反序列化该对象,从而调用构造函数。
请注意,C# 语言和 asp.net 框架处于完全不同的水平。该框架(大部分)是用 C# 编写的,它会在幕后为您做很多事情,但它仍然遵循语言和运行时的规则。
序列化只不过是将对象(或对象图)的信息编码到流中。如果反序列化它,您将得到相同的信息,但它不是您开始时使用的同一对象。再说一遍,这并不神奇,您可以使用属性和反射编写自己的序列化库。
It will increase the seed every time the constructor is invoked. Note that this can happen in multiple threads, so you better make it thread safe.
Deserialization will cause the (default) constructor to be invoked. If you serialize it to the ViewState, then ASP.NET will deserialize the object on postback, and thus invoke the constructor.
Please note that the C# language and the asp.net framework are on a whole other level. The framework is written (largely) in C#, and it will do a lot for you behind the scenes, but it still follows the rules of the language and the runtime.
Serialization is nothing more than encoding the information of an object (or graph of objects) to a stream. If you deserialize it, you will have the same information back, but it is not the same object you started with. Again, it is no magic, you could write your own serialization library using attributes and reflection.