公共共享变量在用户之间共享吗?

5

我接手了网站的维护工作(ASP.NET VB),在某个特定的页面上,我注意到以下代码:

Inherits System.Web.UI.Page

Public Shared UserNumber As String

Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init

    UserNumber = Session("UserNumber")

    ...

End Sub

我的问题是除了当前用户,是否还有其他用户可以访问或更改变量UserNumber?谢谢。

是的,作为“Shared”变量,它可以被所有实例访问...因此,在同一进程上运行的应用程序的所有用户都可以访问它。 - Andrew Barber
2个回答

9

Shared变量与C#中的static变量相同。

这些可以跨所有实例共享,因此不同的用户将共享相同的变量。

从变量名称来看,我会认为您需要删除这个Shared


您正在将Session变量值应用于Page_Init上的Shared String

因此,每次用户加载页面时,它们的会话变量将覆盖当前值。


如果您在此类之外没有使用此变量,则建议将其更改为:

Protected UserNumber As String

那么,如果代码简单地更改为Public UserNumber As String该变量只能被当前用户访问? - DotNetDublin
@BugLover 如果你没有在这个类之外使用这个变量,那么请将它改为“Protected”。 - Curtis
非常感谢Curt,我会将其更改为Protected UserNumber As String,因为它仅在此页面上使用。 - DotNetDublin
2
谈到 ASP.NET 中的静态和实例时值得注意的是,基本上每个请求都由不同的线程处理。但实际上情况更加复杂:http://www.codeproject.com/Articles/38501/Multi-Threading-in-ASP-NET - Tim Schmelter

4

编辑:我的初始答案是错误的。再试一次...

从技术上讲,如@Curt所指,Shared变量在类的实例之间共享。

然而,在当前代码中,由于它在Page_Init中设置为每个用户会话的本地副本的值,因此不太可能共享该值。

可能存在“竞争条件”,即在Page_Init中初始化了共享变量UserNumber后,另一个用户提交请求并从其会话更新该变量的值,那么第一个用户将看到第二个用户的值。也就是说,用户可以看到并发请求的其他用户的值。

相反,我建议使用ReadOnly非共享属性从会话中获取值:

 Private mUserNumber As String
 Public ReadOnly Property UserNumber As String
      Get
           If String.IsNullOrEmpty(mUserNumber) Then
               mUserNumber = Session("UserNumber")
           End If
           Return mUserNumber
      End Get
 End Property

这里使用了一种叫做“延迟加载”的模式,我在页面上的只读属性中经常使用它来提高性能和代码可读性。


谢谢回复,但我看到了矛盾的答案。我知道会话在用户之间是分开的,但我的问题是用户B是否能够影响用户A的变量UserNumber的值? - DotNetDublin
Session 字典是什么,但 Shared String 呢?不同的会话变量是否会更新相同的共享变量? - Curtis
你对Session字典的理解是正确的,但是变量UserNumber(这才是问题所在,而不是Session("UserNumber"))确实是所有用户共享的。 - Heinzi
抱歉GrefL,我现在才看到你编辑过的回复。非常感谢,上面的代码看起来非常有用。 - DotNetDublin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接