2010-05-12 78 views
6

我有一個Web應用程序,我想從數據庫中提取用戶設置並將它們存儲爲全局訪問。將數據存儲在Singleton或Session對象中會更有意義嗎?兩者有什麼區別?會話vs單例模式

是更好的數據存儲爲一個對象引用或它分解成值類型對象(整數和字符串)?

回答

11

會議。這就是它的目的。會話存儲在全局緩存中(基本上是一個單例),由會話ID鍵入。這樣,您只能獲得感興趣的會話數據。使用單例將基本上覆制全局緩存,並且您必須重新創建機制以獨立檢索每個會話的數據。

繼續並存儲對象。讓Session擔心將它序列化爲可以恢復的內容。不過,請注意您在會議中所放的內容。你不想在那裏存儲太多的數據,否則你會用盡大量的內存(假設內存緩存)。

4

如果這些設置將被用於該網站的所有用戶,將它們放在一個單獨或應用程序緩存。如果它們是特定於每個用戶的,則將它們放入會話中。我相信,值類型將得到盒裝,因此看起來像是對象緩存 -

增加了應用程序或會話緩存時,使用對象的引用。如果你使用一個單身人士,它可能會以任何方式。

2

會話對象,當然。

單身在進程級存在。這意味着如果您有20個用戶在任何時候訪問您的網站,他們正在使用相同的單身人士對象。如果你沒有做很多web開發,就很難習慣這個概念。

會話存在於用戶級別。這意味着您可以存儲每個用戶的數據,而不是每個進程。

+0

[應用程序狀態](https://msdn.microsoft.com/en-us/library/ms178594.aspx?f=255&MSPPError=-2147217396)是ASP .Net進程中Singleton的絕佳示例水平。任何適用於網站所有用戶的輕量級鍵值對都可以存儲在其中。這些鍵值對可以通過網絡電話進行訪問。對於重量級或資源密集型的對象,應考慮使用[cache](https://msdn.microsoft.com/en-us/library/ms178597.aspx)。 – RBT 2018-01-23 00:03:35

0

有時候我喜歡下面的方法。它處理魔術字符串和未設置會話變量的問題。它還在會話級別而不是應用程序級別運行單例。

public static SessionHandler GetInstance() 
    { 
     if (HttpContext.Current.Session["SessionHandler"] == null) 
     { 
      HttpContext.Current.Session["SessionHandler"] = new SessionHandler(); 
     } 
     return (SessionHandler)HttpContext.Current.Session["SessionHandler"]; 
    } 

然後,只要使用它作爲一個正常的單身人士。加入你需要的變量。

0

這是從舊文件中獲得,但它仍然是非常有效和作品一種享受......我把鏈接內容在這裏,特別是因爲它是一個古老的鏈接,可能會消失。 Taken from here.

背景

在ASP.Net會話對象可以被用來存儲特定於站點的單個用戶信息。會話通過密鑰名稱進行索引,當以這種方式直接使用時,會導致大量的單個會話名稱。另一種方法是創建一個單例對象來分組相關項目並用給定的鍵名稱存儲該對象。 「單例」是一種常見的設計模式,它指定了如何確保在任何時候只有一個類的單個實例存在。辛格爾頓會議

優勢對象的會話項目

  • 分組爲組織目的
  • 一系列的在瞬態過程頁面,例如在網站上註冊特別有用。一旦這個過程完成,對象可以從會話被清除所以內存可以被回收(更好地利用服務器的 資源)對會話的更改信息的
  • 影響分析是非常容易
  • 識別作爲網站的區域誤用信息(更清晰比只使用變量的名稱,以確定它是否適合使用)
  • 智能感知屬性名稱和類型,一旦訪問該對象

辛格爾頓會議的缺點對象

更難以看到在會議各個項目的數量使用了進程外會話狀態存儲在 ASP.Net跟蹤結果不顯示對象 性能降低內的值(影響序列化)

實施

第一個實施步驟是創建一個類文件,該文件表示應該在單個對象中一起存儲的項目的邏輯分組。以下是演示了該技術的樣本類:

public class singleton 
{ 
    //Name that will be used as key for Session object 
    private const string SESSION_SINGLETON = "SINGLETON"; 

    //Variables to store the data (used to be individual 
    // session key/value pairs) 
    string lastName = ""; 
    string firstName = ""; 

    public string LastName 
    { 
    get 
    { 
     return lastName; 
    } 
    set 
    { 
     lastName = value; 
    } 
    } 

    public string FirstName 
    { 
    get 
    { 
     return firstName; 
    } 
    set 
    { 
     firstName = value; 
    } 
    } 

    //Private constructor so cannot create an instance 
    // without using the correct method. This is 
    // this is critical to properly implementing 
    // as a singleton object, objects of this 
    // class cannot be created from outside this 
    // class 
    private singleton() 
    { 
    } 

    // Create as a static method so this can be called using 
    // just the class name (no object instance is required). 
    // It simplifies other code because it will always return 
    // the single instance of this class, either newly created 
    // or from the session 
    public static singleton GetCurrentSingleton() 
    { 
    singleton oSingleton; 

    if (null == System.Web.HttpContext.Current.Session[SESSION_SINGLETON]) 
    { 
     //No current session object exists, use private constructor to 
     // create an instance, place it into the session 
     oSingleton = new singleton(); 
     System.Web.HttpContext.Current.Session[SESSION_SINGLETON] = oSingleton; 
    } 
    else 
    { 
     //Retrieve the already instance that was already created 
     oSingleton = (singleton)System.Web.HttpContext.Current.Session[SESSION_SINGLETON]; 
    } 

    //Return the single instance of this class that was stored in the session 
    return oSingleton; 
    } 
} 

想要使用這個對象只是執行以下操作的頁面:

singleton oSingleton = singleton.GetCurrentSingleton(); 
oSingleton.FirstName = "Robert"; 
oSingleton.LastName = "Boedigheimer"; 

通常這種技術將更多的變量存儲在給定的類或者將用於執行過程的一系列網頁。在網站上使用這個過程的另一個優點是會話變量所需的所有內存都可以通過簡單地刪除對單例對象的引用來清除。這個類可以實現客戶端可以使用清除參考,它可以被命名的Dispose()的方法遵循典型的.Net模式,當一個類提供一種方式來清理:

public static void Dispose() 
{ 
    //Cleanup this object so that GC can reclaim space 
    System.Web.HttpContext.Current.Session.Remove(SESSION_SINGLETON); 
} 

結論

使用存儲在Session對象中的單例對象而不是使用單個會話密鑰存儲信息有很多優點。對於整個會話中存在的對象(對邏輯項目,影響分析,智能感知等進行分組),特別是對於網站上一段時間只需要的對象,直到用戶完成特定操作過程(當過程完成但會話將繼續時,更容易識別濫用變量並節省資源)。