我有一个名为UserContext
的班级,用于跟踪我网站上给定用户的活动。它应该是一个单例类(每个用户只有一个实例)。在Windows窗体应用程序中,我可以编写如下内容:
Class UserContext
Public Shared Current As New UserContext()
Private Sub New(appName As String)
[...]
End Class
但是在ASP.net应用程序上,这将在所有当前用户之间共享。
如果这个类只在一个Page实体中使用,我可以将UserContext实例存储在一个Page变量中 - 它不一定需要在回发中存活。但是其他实体(不了解Page)也调用UserContext,我希望它们都被赋予相同的实例。
我可以做些什么来确保每个 http请求(或每个用户)只对一个类进行一次实例化?我可以使用缓存吗?
Public Shared Function GetContext() As UserContext
If HttpContext.Current.Cache("CurrentUserContext") Is Nothing Then HttpContext.Current.Cache("CurrentUserContext") = New UserContext()
Return HttpContext.Current.Cache("CurrentUserContext")
End Function
会话状态可能是更好的选择吗?
缓存和会话状态都能在回发中存活 - 是否有另一个选项可以随每个新请求重置?
感谢您的帮助!
答案 0 :(得分:5)
HttpContext.Current.Cache
将在所有用户之间共享。 HttpContext.Current.Session
是每个用户,但会继续存在后续请求。
您需要HttpContext.Current.Items
:
Public Shared Function GetContext() As UserContext
If HttpContext.Current.Items("CurrentUserContext") Is Nothing Then HttpContext.Current.Items("CurrentUserContext") = New UserContext()
Return HttpContext.Current.Items("CurrentUserContext")
End Function
这将确保每个请求和每个用户缓存存储的安全。
答案 1 :(得分:1)
您可以使用HttpContext.Current.Items
集合。
答案 2 :(得分:1)
如果要将变量存储的时间超过请求的生命周期,则需要锁定策略来处理并发请求。始终为您的读取分配,并使用双重检查锁定来强制执行单例。
Private ReadOnly lockObj As New Object()
Private Const CurrentUserContextKey As String = "CurrentUserContext"
Public Function GetContext() As UserContext
Dim session = HttpContext.Current.Session
Dim userContext = TryCast(session(CurrentUserContextKey), UserContext)
If userContext Is Nothing Then
SyncLock lockObj
userContext = TryCast(session(CurrentUserContextKey), UserContext)
If userContext Is Nothing Then
userContext = New UserContext()
session(CurrentUserContextKey) = userContext
End If
End SyncLock
End If
Return userContext
End Function