2010-09-23 71 views
9

我有一個是這樣的每個用戶是否有唯一的靜態對象?

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. 

.NET應用程序(C#)現在的問題是,如果創建並分配給頂部的靜態申報考試theExam的一個實例,用戶105日誌。如果用戶204然後從不同的計算機登錄,則即使在用戶105的計算機上,頂部的靜態對象是否獲得204的值?

回答

10

不,靜態對象是每個人都登錄的同一個實例。此外,該對象並不在105的計算機上,而只在網絡服務器上運行。

+0

澄清:靜態對於應用程序域是唯一的,在這種情況下,這是整個Web應用程序。注意:如果您使用負載均衡,它們在兩臺服務器之間並不是唯一的。所以請記住水平縮放。 – Aren 2010-09-23 22:28:11

+0

如果使用[ThreadStaticAttribute],每個線程將擁有自己的該靜態變量的實例。 – 2010-09-23 23:31:11

+0

的確,但是線程被重用於不同的請求,所以它不夠好。使用會話是這樣的最好的方式。 – 2010-09-23 23:47:30

6

簡短回答:是的,靜態字段對於AppDomain是全局的,因此爲一個用戶執行此操作將爲另一個用戶執行數據操作。

您可能想使用會話存儲,而不是每個用戶的作用域,例如,

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

AppDomain的+1 – 2010-09-23 21:28:14

1

每個AppDomain有一個靜態對象的「實例」。所以你的問題的答案是肯定的。由於您在用戶204登錄時覆蓋變量,因此用戶105也會看到相同的值。

一些一般性的建議

  • 避免靜態字段儘可能
  • 使用會話在用戶的瀏覽會話
    Session["exam"] = currentUser.Exam;
  • 使用配置文件提供了持續的有關信息的情況下存儲臨時信息每個用戶在會話之間。
+2

我認爲「儘可能避免使用靜態字段」的做法有點過頭了。我看到有人害怕使用它們,因爲他們不明白他們是如何工作的,有人告訴他們他們可能會搞砸了。使用它們並使許多事情變得如此簡單(輔助方法,緩存在內存中)沒有任何問題。你只需要知道如何正確使用它們。 – 2010-09-23 21:21:44

+0

@Matti - 一種方法不是一個領域。輔助方法沒有錯。 *您只需要知道如何正確使用它們* - 同意! :) – Venemo 2010-09-23 21:34:16

+0

我見過害怕整個關鍵字'static'的人:我 – 2010-09-23 21:38:28

0

.Net中還有一個[ThreadStatic]屬性,它將爲每個線程創建一個靜態實例。

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

+0

這很好,你提到它,但在這種情況下它也會很糟糕,因爲線程在ASP.NET線程池中被重用。 – 2010-09-23 21:35:21

+2

但是,線程並非專用於每個用戶。即使一個請求也不能保證始終保持在同一個線程中。因此,線程狀態大多(如果不是完全)在Web應用程序中無用。 – Guffa 2010-09-23 21:39:15

7

靜態變量和用戶會話的壽命是不同的概念。靜態變量具有由CLR限定的壽命,並且基本上歸結於以下2條規則

  1. 有一個存儲位置,每AppDomain
  2. 一個通用類型的每個獨特instatiation一個靜態變量創建一個不同的靜態變量。

我發現很難寫出第二條規則,但它不明確獨特。基本上MyType<int>MyType<string>每個都有不同的靜態變量。而MyType<int>MyType<int>共享一個。

用戶對Web服務器的訪問不影響其中任何一個。

如果您希望獲得每個用戶的數據,請使用Session來存儲數據。

Session["examKey"] = theExam; 
+0

+1用於解釋泛型類型。 – 2010-09-23 21:46:04

+0

我不知道我是否做得對,但基本上我做的是考試newExam =新考試(價值,價值);會話[「someKey」] = newExam,然後我只是像考試theExam =(考試)會議[「someKey」]演員會話[「someKey」],所以我可以得到的對象...這是做到這一點的正確方法? – Migs 2010-09-23 22:28:43

相關問題