静态C#类变量在ASP.NET中有什么作用?

3

我知道静态类变量在C++类中的作用,但是我对于在ASP.NET Web应用程序中使用的C#类中的静态类变量的生命周期并不是很清楚。下面是一个代码示例:

namespace MyWebApp
{
    public static class MyFunctions
    {
        private static string _cachedID;

        public static string getID(string strValue)
        {
            if(_cachedID == null)
                _cachedID = strValue;

            return _cachedID;
        }
    }
}

有人能用简单易懂的英语解释一下吗?

3个回答

5

我曾在某处读到:

静态变量/字段在其所在类型的静态构造函数执行之前就已经存在,并在关联应用程序域停止存在时停止存在。


谢谢。那么,比如说,如果我的网络应用程序被发布在www.mydomain.com URL上,并且第一个用户通过Web浏览器登录。那么cachedID变量就会被设置。但是,如果来自另一台计算机的完全不同的用户登录到相同的URL,则cachedID将已经设置为该第一个值。这就是你的意思吗? - ahmd0
1
@ahmd0,是的。整个AppDomain只有一个静态成员实例。 - Alexei Levenkov
@AlexeiLevenkov,单例设计模式与静态字段有所区别(在应用程序域的生命周期内仅可能分配一个实例到静态字段),而普通的静态字段则可以在应用程序域的生命周期内分配多个实例。 - Darin Dimitrov
@DarinDimitrov,嗯...我不太确定如何表达静态字段只分配一次并在整个AppDomain中共享的事实。我的尝试是“静态成员的实例”,但现在我可以看到这可能被解读为单例模式的引用。 - Alexei Levenkov
1
“静态字段仅分配一次并在整个应用程序域中共享” -> 像这样非常完美。没有更多的混淆。 - Darin Dimitrov

1

由于您在多线程ASP.NET应用程序的上下文中提出了这个问题,所以您应该非常小心。请查看以下场景:

2个用户Bob和Alice同时调用getID方法并传递不同的参数。Bob传递Foo,而Alice传递Bar。由于这是第一次调用,因此_cachedID变量尚未初始化,因此两者都进入if条件,Bob稍有延迟。因此,Alice将_cachedID静态变量设置为Bar,然后微秒后,Bob将其设置为Foo。现在代码继续执行,并且函数对于两个用户都返回Foo。当然,Bob很高兴,因为这就是他想要的,但是Alice想要Bar

例如,如果您想在多线程环境中执行一次性初始化,则可以考虑使用Singleton Pattern的线程安全版本。

这个故事告诉我们,在处理ASP.NET应用程序中的共享/静态数据时,一定要非常小心。如果需要使用它,必须正确同步对其的访问,否则会发生非常糟糕的事情。而且通常在多个用户同时访问您的应用程序时才会发生。在您的本地PC上,一切都将正常工作。
至于您最初提出的关于静态字段寿命的问题:它与应用程序域的寿命相关联。

谢谢,Darin。它解释得很清楚。我会记住的。不过有一个旁边的问题——当我们谈论Web浏览器访问我的Web应用程序时,IIS服务器如何记住那个变量呢? - ahmd0
IIS不会记住任何东西。它是你的ASP.NET应用程序执行的应用程序域将其存储在内存中。 - Darin Dimitrov

0

谢谢提供链接。我不太清楚在ASP.NET环境中这些静态变量的生命周期是怎样的? - ahmd0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接