【问题标题】:Are static objects unique per user?每个用户的静态对象是唯一的吗?
【发布时间】:2010-09-23 21:09:27
【问题描述】:

我有一个类似这样的 .net 应用程序 (c#)

public partial class _Default : System.Web.UI.Page
{
    #region initial variables setup

    private static exam theExam;

    #endregion


    protected void Page_Load(object sender, EventArgs e)
    {
       if(!IsPostBack)
       {
        string userid = Request.Querystring["user"].ToString();
           theExam = new exam(userid, "some values");
       }
    }
// rest of code.

现在我的问题是,如果用户 105 登录考试实例,则创建考试并分配给顶部的静态声明。如果用户 204 然后从另一台计算机登录,即使在用户 105 的计算机上,顶部的静态对象是否也会获得 204 的值?

【问题讨论】:

    标签: c# asp.net static object


    【解决方案1】:

    不,静态对象对于每个登录的人来说都是同一个实例。此外,该对象并不存在于 105 的计算机上,而只是存在于网络服务器上。

    【讨论】:

    • 为了澄清:静态是应用程序域独有的,在这种情况下,它是整个网络应用程序。注意:如果您使用负载平衡,它们在两台以上的服务器中并不是唯一的。因此,请记住这一点以进行水平缩放。
    • 如果你使用 [ThreadStaticAttribute] 每个线程都会有它自己的静态变量实例。
    • 确实如此,但是线程被重用于不同的请求,所以还不够好。使用 Session 是处理此类事情的最佳方式。
    • 当然。会话是应该使用的。在 ASP.NET 中使用静态变量是个坏主意。我在回复 Aren 时主要评论说静态不一定只是应用程序域独有的。
    【解决方案2】:

    静态变量的生命周期和用户会话是非常不同的概念。静态变量的生命周期由 CLR 定义,基本上归结为以下 2 条规则

    1. 每个AppDomain 都有一个静态变量的存储位置
    2. 泛型类型的每个唯一实例化都会创建一个不同的静态变量。

    我发现很难写出第二条规则而不使 unique 模棱两可。本质上MyType<int>MyType<string> 都有不同的静态变量。而MyType<int>MyType<int> 共享同一个。

    用户对网络服务器的访问不会影响其中任何一个。

    如果您想拥有每个用户的数据,请使用Session 来存储数据。

    Session["examKey"] = theExam;
    

    【讨论】:

    • 我不确定我是否做对了,但基本上我所做的是exam newExam = new Exam(value, value); Session["someKey"] = newExam,然后我只使用像考试 theExam = (exam) Session["someKey"] 这样的 Session["someKey"] 这样我就可以获得对象......这是正确的方法吗?
    【解决方案3】:

    简短的回答:是的,静态字段对于 AppDomain 来说是全局的,因此为一个用户执行此操作将踩到另一个用户的数据。

    您可能想考虑使用会话存储,它是针对每个用户的,例如

    var theExam = Session["exam"] as Exam;
    

    【讨论】:

      【解决方案4】:

      每个 AppDomain 都有一个静态对象的“实例”。所以你的问题的答案是肯定的。由于您在用户 204 登录时覆盖了该变量,因此用户 105 也会出现相同的值。

      一些一般性建议

      • 尽可能避免使用静态字段
      • 使用 Session 在用户浏览会话的上下文中存储临时信息
        Session["exam"] = currentUser.Exam;
      • 使用 Profile Provider 在会话之间持久保存每个用户的信息。

      【讨论】:

      • 我认为说“尽可能避免使用静态字段”有点过头了。我见过有人害怕使用它们,因为他们不了解它们是如何工作的,有人告诉他们他们可能会把事情搞砸。使用它们并没有什么问题,并且使许多事情变得如此简单(帮助方法,在内存中缓存)。你只需要知道如何正确使用它们。
      • @Matti - 方法不是字段。辅助方法没有任何问题。 您只需要知道如何正确使用它们 - 同意! :)
      • 我见过害怕整个关键字static的人:我
      • @Matti - 我也是,但更多的是在 C/C++ 的上下文中而不是 C#
      【解决方案5】:

      .Net 中还有一个 [ThreadStatic] 属性,可以为每个线程创建一个静态实例。

      http://msdn.microsoft.com/en-us/library/system.threadstaticattribute(VS.71).aspx

      【讨论】:

      • 你提到它很好,但在这种情况下它也很糟糕,因为线程在 ASP.NET 线程池中被重用。
      • 但是,线程并不是为每个用户专用的。甚至不能保证单个请求从头到尾都留在同一个线程中。因此,线程静态在 Web 应用程序中大部分(如果不是完全)无用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-25
      • 1970-01-01
      • 2020-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多