【问题标题】:What is the catch with ASP.NET singleton?ASP.NET 单例有什么问题?
【发布时间】:2014-09-15 06:13:35
【问题描述】:

我浏览了很多关于 stackoverflow 的链接,例如 thisthisthis one。答案到处都表明,静态变量对于整个应用程序域都是静态的。这正是我所期待的。但我观察到的行为并非如此。这是我的代码:

public static class CurrentGrid
{
    private static readonly Grid g;
    static CurrentGrid()
    {
        g = new Grid();
    }
    public static Grid Get { get { return g; } }
}

我从 global.asax.cs AppStart 方法中调用它,如下所示:

if (Application["CurrentGrid"] == null)
    Application["CurrentGrid"] = CurrentGrid.Get;

我只想在整个应用程序生命周期内初始化网格ONCE。但它没有发生。每次,我都会得到一个 Grid 对象的新实例。我试过了,使用

Application["CurrentGrid"] = new Grid()

但这也没有用。正如上述链接问题中的一个答案所建议的那样,我什至将类定义从 App_Start 文件夹移至 Models 文件夹,但行为仍然保持不变。最后我尝试使用静态构造函数来初始化 Grid 对象一次,但即使是这个静态构造函数也会在每次新请求到来时被触发。

另外,我看到的另一种奇怪的行为是,Application_Start() 也会为每个请求调用。我认为这个方法在应用程序第一次启动时只被调用一次。我想,我在 OOP 或 ASP.NET 框架的一些非常基本/核心的原则上弄错了,因为我找不到任何关于这种行为的解释。谢谢。

PS: 1) 只是提醒一下,我在这里的唯一目标是在整个应用程序生命周期内拥有一个单例 Grid 对象。 2) 我在 MVC5 和 SignalR 应用程序中执行所有这些操作(以防万一)。

PS:PROJECT ON GDRIVE

【问题讨论】:

  • 您是否在请求之间对您的应用程序进行了更改?如果是这样,那可能(我不是 ASP.NET 方面的专家,但这是有道理的)触发重新编译和新的 AppDomain。我会关注 Application_Start 被调用的频率比预期的要高的事实——我怀疑这是导致其他一切出错的最简单的症状。
  • @JonSkeet 不,我认为这不会导致重新编译。可能是因为一些 SignalR/OWIN 的东西???
  • 是否有可能改变您的 web.config?这将导致应用程序重新启动。
  • @arao6 这不是我的第一次尝试。在做了很多其他事情之后,我终于到达了这里,当时我想我应该把这个作为一个问题发布在 SO 上。但是,正如 cmets 中所指出的,主要问题是 Application_Start 被多次调用。
  • 确保您没有将任何日志条目写入 bin 文件夹。

标签: c# asp.net .net asp.net-mvc singleton


【解决方案1】:

确保您没有将任何日志条目(创建或修改文件)写入 bin 文件夹。

【讨论】:

  • 确实将任何内容写入 bin 文件夹或其任何子文件夹会导致重新编译并重新启动应用程序。
【解决方案2】:

也许这会有所帮助?

static CurrentGrid()
{
   if(g == null)
   {
      g = new Grid();
   }
}

或者甚至更好;

public static class CurrentGrid
{
    private static readonly Grid g;
    static CurrentGrid()
    {
        //Do Grid things her
    }
    public static Grid Get { 
                              get 
                              { 
                                if(g == null)
                                { 
                                   g = new CurrentGrid(); 
                                }

                                return g; 
                              } 
                           }
}

这样做,你肯定只会得到一个 Grid-object,除非你当然处置它。

【讨论】:

  • 我认为这行不通。听起来应用程序在每次请求后都会重新启动(这是不正常的)。这意味着所有状态都丢失了。
  • @Dion 是的,对于每个请求,g 始终为空。由于该应用程序似乎作为一个全新的应用程序运行(只是类比)。
  • 我很抱歉没有阅读整个问题。看来这确实不是问题。在您阅读此评论后,我将删除此帖子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多