簡體   English   中英

Web應用程序中的單例模式

[英]Singleton pattern in web applications

我在我的Web應用程序中使用單例模式作為datacontext,因此我不必每次都實例化它,但是我不確定Web應用程序是如何工作的,IIS是否為每個連接的用戶打開一個線程? 如果是這樣,如果我的單例不是線程安全會發生什么? 另外,對於datacontext使用單例模式是否可以? 謝謝。

我在我的Web應用程序中使用單例模式作為datacontext

在這種情況下,“單身人士”可能意味着許多不同的事物。 是每個請求的單實例嗎? 每次會話? 每個線程? 每AppDomain( static實例)? 所有這些的影響是截然不同的。

每個請求(存儲在HttpContext )的“單例”很好。 不鼓勵每個會話單身,但可以使其工作。 每個線程的單例可能看起來有效,但很可能導致意外和難以調試的行為。 每個應用程序或AppDomain的單例是等待發生的災難。

所以我不必每次都實例化它

創建DataContext非常非常便宜。 元數據是全局緩存的,在實際執行查詢之前不會創建連接。 沒有理由嘗試優化DataContext實例的構造。

但是我不確定Web應用程序是如何工作的,IIS是否為每個連接的用戶打開了一個線程?

IIS為每個請求使用不同的線程,但是單個請求可能使用多個線程,並且線程從線程池中獲取,這意味着最終同一個用戶將在許多不同的線程上發出請求,相反,不同的用戶將共享多個請求和延長的時間段內的相同線程。 這就是為什么我在上面提到你不能依賴Thread-Local Singleton。

如果是這樣,如果我的單例不是線程安全會發生什么?

非常糟糕的事情。 您在ASP.NET應用程序中全局緩存的任何內容都需要設置為線程安全或需要在使用時鎖定。

另外,對於datacontext使用單例模式是否可以? 謝謝。

DataContext不是線程安全的,在這種情況下,即使您在使用DataContext時鎖定它(這已經不是一個好主意),您仍然可能遇到跨線程/交叉請求競爭條件。 不要這樣做。

應盡可能使用using子句將DataContext實例限制在單個方法的范圍內。 接下來最好的事情是將它們存儲在HttpContext 如果必須,您可以在Session中存儲一個,但是您需要注意很多事情(請參閱我最近在ObjectContext上回答的這個問題 - 幾乎所有相同的原則都適用於DataContext )。

但最重要的是, 不要在ASP.NET應用程序中創建DataContext “全局”單例實例。 你以后會后悔的。

許多人在請求期間保留DataContext,方法是將其保存在HttpContext.Current.Items因此,它也是請求的私有。

看看Steve Sanderson撰寫的這篇博文 ,以及UnitOfWork模式

每個應用程序域上的所有用戶都可以看到靜態變量,而不是每個會話。 一旦創建,變量將在應用程序域的生命周期內存儲在內存中,即使沒有對該對象的活動引用也是如此。

因此,如果您在Web應用程序中有某些其他用戶不應該看到的有狀態信息,那么它絕對應該是靜態的。 將這種信息存儲在用戶會話中,或將靜態var轉換為如下所示:

public static Data SomeData
{
    get
    {
        if (HttpContext.Session["SomeData"] == null)
            HttpContext.Session["SomeData"] = new Data();
        return (Data)HttpContext.Session["SomeData"];
    }
}

看起來像一個靜態變量,但它的會話特定,因此當會話終止時數據被垃圾收集,而其他用戶完全看不到它。 安全無法保證。

另外,如果你在靜態變量中有狀態信息,你需要某種類型的同步來修改它,否則你將會遇到種族條件的噩夢來解開。

@ryudice Web服務器為每個請求創建一個新線程。 我認為最好的方法是將datacontext綁定到每個請求,這意味着每次提交請求時都應該創建一個新的datacontext。 實現這一目標的一個好方法是使用DI工具,例如StructureMap 這些工具允許您設置所配置實例的生命周期,因此在您的情況下,您可以將XDataContext類配置為HttpContext作用域。

問候。

以下是Microsoft關於如何使用LINQ-To-SQL執行多層的示例。

http://code.msdn.microsoft.com/multitierlinqtosql

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM