我想在应用程序启动时实例化一个对象,并希望维护它,直到应用程序结束或我手动更新它。
我以为我可以用public static class
来做,但它不起作用。如果我创建这个类:
public static class MyGlobalClass
{
private static object _MyObject;
static MyGlobalClass
{
_MyObject = new object();
}
public static object GetObject()
{
return _MyObject;
}
}
我创建了一个aspx页面,如:
public partial class MyPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
object obj = MyGlobalClass.GetObject();
}
}
如果我调试这个例子,在每次请求时都会调用静态构造函数,所以对象_MyObject
每次都会初始化,而不是像我想的那样只初始化一次。
在我的情况下,对象的初始化是昂贵的,所以我只想实例化它一次,只想手动更新它。
我必须告诉ASP.NET将public static class
保存在内存中吗?看起来ASP.NET在每次请求后都会丢弃整个类MyGlobalClass
。
更新
即使应用程序状态始终为空:
public static class MyGlobalClass
{
private static object _MyObject;
static MyGlobalClass
{
if(HttpContext.Current.Application["MyObject"] != null)
{
_MyObject= (object)HttpContext.Current.Application["MyObject"];
return;
}
_MyObject = new object();
HttpContext.Current.Application["MyObject"] = _MyObject;
}
public static object GetObject()
{
return _MyObject;
}
}
对于每个请求,应用程序状态都为空。
有一个名为Singleton的模式,这可能会对您有所帮助。
public class MyGlobalClass
{
private static MyGlobalClass _instance;
private static object _myObject;
protected MyGlobalClass()
{
if (HttpContext.Current.Application["MyObject"] != null)
{
_myObject = (object)HttpContext.Current.Application["MyObject"];
return;
}
_myObject = new object();
HttpContext.Current.Application["MyObject"] = _myObject;
}
public static MyGlobalClass GetInstance()
{
if (_instance == null)
{
_instance = new MyGlobalClass();
}
return _instance;
}
public static object GetObject()
{
return _myObject;
}
}
您只需要调用GetInstance()方法来实例化MyGlobalClass的新对象。
我现在开始工作了,但我认为这不是一个好方法:
我必须在Global.asax文件中保留静态变量:
public class Global : System.Web.HttpApplication
{
public static object MyObject { get; private set; }
protected void Application_Start(object sender, EventArgs e)
{
MyObject = new object();
}
}
现在我可以用Global.MyObject访问对象了。奇怪的是,这应该和第一个自定义静态类的例子一样,但自定义静态类总是被丢弃。
最后一件奇怪的事情是为什么Application_Start
方法被调用了3次。我在Applicationpool的高级设置中将Workerprocesses设置为1,所以我不明白为什么Application_Start
被调用了3次。
不管怎样,对象被初始化3次,因为Application_Start
被调用了3次,但在那之后,它可以在不重新创建的情况下使用。如果我需要重新创建它,我会在Global.asax.中使用静态方法手动创建
更新
问题很简单,但我以前并不知道:每当bin文件夹中发生更改时,IIS都会重新启动应用程序池。我为全局变量创建了一个新的AppDomain
,启用了ShadowCopy
,并将缓存文件夹作为bin中的子文件夹。所以每次我创建AppDomain
时,bin文件夹都会发生变化,Apppool也会重新启动,所以Application_Start
被调用了不止一次。我把缓存目录从bin移到了外面,现在一切都很好。