用于整个应用程序的C#ASP.NET全局变量



我想在应用程序启动时实例化一个对象,并希望维护它,直到应用程序结束或我手动更新它。

我以为我可以用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移到了外面,现在一切都很好。

相关内容

  • 没有找到相关文章

最新更新