Asp.net 类实例中的私有共享值如何以及为什么在http请求之间存活?
我们有一个大型asp.net应用程序(用vb.net编写)。我们所有的定制类都以.vb文件的形式存储在App_代码文件夹中 其中一个类的行为非常令人窒息——特别是,它的私有成员在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 =
'#### 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),它有自己的代码隐藏页面,其中包含相同的代码-即它自己的类实例-或者我们所想的那样
发生的情况如下(通过调试器验证):
xxxUtilities
的实例,m_ajax
成员保持false
xxxUtilities
实例,并将m_ajax
设置为true
,然后正常返回xxxUtilities
的新实例,作为普通实例-将值传递给构造函数-但令我们惊讶的是,m_ajax
是真的吗李>
这提出了三个问题:
m_ajax
的正确性如何以及为什么?ajax实例是否留在内存中,当后续的default.aspx请求一个新实例时,它只是链接到现有的实例或其他什么.CloseDatabase()
,则即使在http请求结束后,与SQL server的连接仍然保持打开状态-这是同一个问题吗?i、 e.http请求结束后,数据库类的实例是否留在内存中?)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年代,我们就使用静态
缓存应用程序数据。现在有更好的方法。