Asp.net Global.asax中的共享/静态变量是否按请求隔离?
我有一些ASP.NET web服务,它们都共享一个公共帮助器类,它们只需要为每台服务器实例化一个实例。它用于数据的简单转换,但在启动时确实会花费一些时间从web.config文件等加载内容。helper类是100%线程安全的。将其视为一个简单的实用程序调用库。我想在类上共享所有方法,但我想从web.config加载初始配置。我们已经将web服务部署到IIS6.0中,并使用了一个应用程序池,其中有15名工作人员 我在Global.asax中将helper类声明为私有共享变量,并添加了一个延迟加载共享只读属性,如下所示:Asp.net Global.asax中的共享/静态变量是否按请求隔离?,asp.net,vb.net,web-services,Asp.net,Vb.net,Web Services,我有一些ASP.NET web服务,它们都共享一个公共帮助器类,它们只需要为每台服务器实例化一个实例。它用于数据的简单转换,但在启动时确实会花费一些时间从web.config文件等加载内容。helper类是100%线程安全的。将其视为一个简单的实用程序调用库。我想在类上共享所有方法,但我想从web.config加载初始配置。我们已经将web服务部署到IIS6.0中,并使用了一个应用程序池,其中有15名工作人员 我在Global.asax中将helper类声明为私有共享变量,并添加了一个延迟加载共
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并没有起到很大的作用
我尝试过使用
应用程序(“助手”)
和缓存(“助手”)
做类似的事情,但我仍然看到构造函数在每个请求中运行。过去我在自己的应用程序中做过类似的事情,它导致了各种奇怪的错误。
每个用户都可以访问该属性中其他所有人的数据。另外,你可能会有一个用户正在使用它,而不是因为它被另一个用户请求而被切断。
不,没有隔离。您可以将助手置于应用程序状态。在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实例只发生一次,而不是每个请求。除非您绝对需要,否则使用应用程序状态是不明智的,如果您坚持使用每个请求对象,事情会简单得多。向助手类添加任何状态都可能导致各种细微错误。使用HttpContext.Current items集合并根据请求初始化它。VB模块可以做你想做的事情,但你必须确保它不是有状态的。这会在每个请求上实例化一个新对象——我认为Bob试图在每个服务器上获得一个对象。Michael——我不认为这会在每个请求上实例化一个新对象。对象在应用程序启动时创建,只创建一次。第二部分只是指定一个对象变量来指向现有对象。整个时间内只有一个对象实例。元素_15939绝对正确。每个应用程序一个对象,而不是每个请求一个对象。每次应用程序重新启动时都会创建一个新的应用程序(例如,在iisreset或服务器重新启动之后…),对于昂贵的对象来说,为每个请求重新创建它们是非常糟糕的主意。如果你的网站流量很低,但一旦你的服务器负载很重,它就会杀死你。