代码之家  ›  专栏  ›  技术社区  ›  Bob King

global.asax中的共享/静态变量是否按请求隔离?

  •  3
  • Bob King  · 技术社区  · 16 年前

    我有一些ASP.NET Web服务,它们都共享一个公共的助手类,它们只需要实例化 每个服务器 . 它用于简单的数据转换,但在从web.config文件等加载内容的启动过程中确实花费了一些时间。 帮助程序类是100%线程安全的。把它想象成一个简单的实用程序调用库。我将在类上共享所有方法,但我想从web.config加载初始配置。 我们已经将Web服务部署到了IIS6.0,并使用了一个应用程序池,其中有一个由15名工作人员组成的Web花园。

    我在global.asax中将helper类声明为私有共享变量,并添加了一个lazy load shared readonly属性,如下所示:

    Private Shared _helper As MyHelperClass
    
    Public Shared ReadOnly Property Helper() As MyHelperClass
        Get
            If _helper Is Nothing Then
                _helper = New MyHelperClass()
            End If
            Return _helper
        End Get
    End Property
    

    我在构造函数中为 MyHelperClass() 它显示为每个请求运行的构造函数,即使在同一线程上也是如此。我确信我只是缺少了ASP.NET的一些关键细节,但MSDN并没有起到很大的作用。

    我试过用这两种方法做类似的事情 Application("Helper") Cache("Helper") 我仍然看到构造函数与每个请求一起运行。

    3 回复  |  直到 9 年前
        1
  •  0
  •   user7375    16 年前

    除非您绝对需要,否则使用应用程序状态是不明智的,如果您坚持使用每个请求对象,事情会简单得多。向助手类中添加任何状态都可能导致各种细微的错误。使用httpcontext.current items集合,并根据请求对其进行初始化。一个vb模块可以做你想做的,但是你必须确保它不具有状态性。

        2
  •  3
  •   JRoppert    16 年前

    您可以将助手置于应用程序状态。在global.asax中执行此操作:

      void Application_Start(object sender, EventArgs e)
      {
        Application.Add("MyHelper", new MyHelperClass());
      }
    

    您可以这样使用助手:

      MyHelperClass helper = (MyHelperClass)HttpContext.Current.Application["MyHelper"];
      helper.Foo();
    

    这将导致在应用程序启动时创建并处于应用程序状态的MyHelperClass类的单个实例。由于实例是在应用程序_start中创建的,因此对于每个httpapplication实例,这只会发生一次,而不是每个请求。

        3
  •  0
  •   Donny V.    16 年前

    我以前在自己的应用程序中做过类似的事情,它导致了各种各样的奇怪错误。 每个用户都可以访问该属性中其他所有人的数据。另外,你最终可能会发现一个用户正在使用它,而不是因为另一个用户请求它而被切断。

    不,没有孤立。