Asp.net 类实例中的私有共享值如何以及为什么在http请求之间存活?

Asp.net 类实例中的私有共享值如何以及为什么在http请求之间存活?,asp.net,.net,ajax,vb.net,Asp.net,.net,Ajax,Vb.net,我们有一个大型asp.net应用程序(用vb.net编写)。我们所有的定制类都以.vb文件的形式存储在App_代码文件夹中 其中一个类的行为非常令人窒息——特别是,它的私有成员在http请求之间生存——即使在调用构造函数之后也是如此 让我给你一个简化的例子,类是巨大的,但类声明是完全常规的: '#### App_Code/Common/xxxUtilities.vb Public Class xxxUtilities Private Shared m_ajax As Boolean =

我们有一个大型asp.net应用程序(用vb.net编写)。我们所有的定制类都以.vb文件的形式存储在App_代码文件夹中

其中一个类的行为非常令人窒息——特别是,它的私有成员在http请求之间生存——即使在调用构造函数之后也是如此

让我给你一个简化的例子,类是巨大的,但类声明是完全常规的:

'#### App_Code/Common/xxxUtilities.vb
Public Class xxxUtilities
    Private Shared m_ajax As Boolean = False
    Public Class CommonHTML
        Public Sub Whatever()
            '#### Share the value of m_ajax here
        End Sub
    End Class
End Class
我们在别处有一个典型的aspx codebehind页面,以通常的方式声明该类的一个实例-让我们称之为default.aspx:

Public SF As New xxxUtilities(db, CurrentUser)
还有一个单独的aspx页面(在ajax操作中使用-让我们称之为ajax.aspx),它有自己的代码隐藏页面,其中包含相同的代码-即它自己的类实例-或者我们所想的那样

发生的情况如下(通过调试器验证):

  • default.aspx正在加载,正常创建
    xxxUtilities
    的实例,
    m_ajax
    成员保持
    false
  • default.aspx使用jQuery调用ajax.aspxajax.aspx创建(我们认为是)自己的
    xxxUtilities
    实例,并将
    m_ajax
    设置为
    true
    ,然后正常返回
  • 当我们下一次刷新default.aspx并逐步遍历代码时,它会创建一个
    xxxUtilities
    的新实例,作为普通实例-将值传递给构造函数-但令我们惊讶的是,
    m_ajax
    是真的吗 这提出了三个问题:

  • 在最后一步中,
    m_ajax
    的正确性如何以及为什么?ajax实例是否留在内存中,当后续的default.aspx请求一个新实例时,它只是链接到现有的实例或其他什么

  • 有没有办法确保在http请求结束时完全处理自定义类的任何实例

  • 数据库类(同样位于App_代码中)也存在同样的问题,如果我们忘记调用.CloseDatabase(),则即使在http请求结束后,与SQL server的连接仍然保持打开状态-这是同一个问题吗?i、 e.http请求结束后,数据库类的实例是否留在内存中?)

  • 我们如何修改(即真实世界的代码/示例)default.aspx/xxxUtilities.vb以防止这种行为


  • Shared
    关键字与C#中的
    static
    关键字相同。这意味着这样修饰的字段与类关联,而不是与类的实例关联

    在重置应用程序域之前,存储将一直存在

    在最后一步中,m_ajax是如何实现的&为什么实现的?ajax实例是否留在内存中,当后续的default.aspx请求一个新实例时,它只是链接到现有的实例或其他什么

    实例已保留内存,但共享字段未与实例关联。请注意,当前正在运行的所有HTTP请求都将看到相同的m_ajax字段。这可能会导致当前编码的并发问题

    有没有办法确保在http请求结束时完全处理自定义类的任何实例

    不要使用共享字段

    数据库类(同样位于App_代码中)也存在同样的问题,如果我们忘记调用.CloseDatabase(),则即使在http请求结束后,与SQL server的连接仍然保持打开状态


    使用处理每个HTTP请求的代码中的语句打开和关闭数据库连接。

    共享的
    /
    静态的
    在涉及多线程和基于web的代码时不是您的朋友。正如Eric所指出的,它将在所有上下文中保持不变,因为它与该类的任何特定实例都不相关。@TyCobb:早在.NET 1.1/.NET 2.0年代,我们就使用
    静态
    缓存应用程序数据。现在有更好的方法。