每个请求隔离的Global.asax中的共享/静态变量?

时间:2008-09-15 12:59:24

标签: asp.net vb.net web-services

我有一些ASP.NET Web服务,它们共享一个公共帮助程序类,它们只需要实例化每个服务器的一个实例。它用于简单的数据转换,但在启动时会花费一些时间从web.config文件中加载东西等。帮助程序类是100%线程安全的。可以把它想象成一个简单的实用程序调用库。我将在类上共享所有方法,但我想从web.config加载初始配置。我们已经将Web服务部署到IIS 6.0并使用应用程序池,Web Garden of 15名工人。

我将帮助器类声明为Global.asax中的Private Shared变量,并添加了一个延迟加载的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 个答案:

答案 0 :(得分:3)

您可以将助手置于申请状态。在global.asax中执行此操作:

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

你可以这样使用助手:

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

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

答案 1 :(得分:0)

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

没有孤立的。

答案 2 :(得分:0)

使用应用程序状态是不明智的,除非你绝对需要它,如果你坚持使用每个请求对象,事情就会简单得多。向助手类添加任何状态都可能导致各种细微错误。使用HttpContext.Current项集合并按请求初始化它。一个VB模块可以做你想要的,但你必须确保不要使它成为有状态。