2010-03-24 20 views
1

我有以下情況:Singleton類上的多個虛擬目錄使用

  • 多在同一個應用程序池虛擬目錄在IIS
  • 同一個DLL的
  • 副本在所有這些目錄(版本號相同)
  • 在一個單例類此DLL

的問題是,所有這些虛擬目錄實例創建一次此singleton類或者是有這些迪一個單獨的單身人士課程。

的代碼看起來是這樣的:

[ 
Transaction(TransactionOption.Supported), 
ClassInterface(ClassInterfaceType.AutoDispatch), 
Guid("7DE45C4D-19BE-4AA4-A2DA-F4D86E6502A8") 
] 
public class SomeClass 
{ 
    private static readonly Singleton singleton = new Singleton(); 

回答

7

單身會使用它的每個應用程序創建。每個應用程序彼此分開,因爲它們都存在於各自的application domain中。爲了在不同的應用程序中擁有一個真正的單例類,您需要讓它們與持有該信息的通用應用程序(如通過遠程處理或WCF等)進行通信。

application pool控制該池中有多少內存和處理器應用程序可以訪問(以及程序運行的帳戶)。他們仍然彼此分開。

1

在II中,每個虛擬目錄都有一個與之關聯的應用程序。應用程序不會與其他應用程序共享內存空間,因此每個虛擬目錄都會有一個此類的新實例。

您可以創建所有這些應用程序將使用的共享應用程序池。但是,在這種情況下,內存將被共享,但每個內存都將使用該內存獲得唯一的進程,每個獨特的進程將加載該類。

1

將來自不同位置的程序集(DLL)加載到.net CLR中(甚至將相同文件的相同副本放入同一個進程(*)),CLR將它們當作獨立的程序集處理......因此,類型在這些程序集中 - 儘管語法上相同(即使在名稱空間方面) - 仍然是不同的類型!因此,即使它們處於同一個應用程序上下文(OS進程)中,該單例也不會成爲跨調用方的單個公共實例(您將有三個單獨的同一類的靜態實例)。另外:應用程序上下文被定義爲具有基本路徑(在ASP.Net的情況下,這是虛擬目錄)......進一步證明Web應用程序全部在單獨的進程中運行(凱文是正確的)。雖然:全局程序集緩存(GAC)帶有不同的挑戰......但CLR對「DLL地獄」的迴應是將每一個對象不同的文件(相同的副本或不同)作爲一個單獨的程序集...使用GAC - 我強烈建議不要將程序集複製到單個機器上的多個位置。如果沒有別的:這種文件複製是一個部署的噩夢。 GAC附帶各種功能強大的版本管理實用程序以引導(檢出:GAC綁定策略)。

希望能幫助您的長期解決方案...

Aidanapword

(*),這可以通過使用反射來完成...不是一個好主意,但它發生。

1

首先說明 - 當您在IIS 6和7下運行時,如果允許IIS爲每個AppPool使用多個進程,AppDomains可以位於單獨的工作進程中。爲了將其置於恰當的歷史背景下,AppDomain只是模擬IIS AppPool機制對任何二進制文件所做的事情。允許大量的可擴展性,並且在很多情況下,如果你有幾個「singleton」的副本,這也可以提高性能。

如果你真的真的,我的意思是真的:-)需要一個服務器級別的單身人士,有一種方法可以做到這一點,而無需支付遠程處理的費用,但只有當你知道你的COM或WinNT API。

WinNT路由將是最輕的資源方式,但您必須完成WinNT工作,以至於您會開始問爲什麼您仍然使用C#而不是C++ - 共享內存,事件或WinNT互斥鎖等

COM路徑將要求您強制執行proc調用(正確的註冊表項),您可能想要使用AutoDual而不是AutoDispatch - 首先購買perf,然後再確保.NET具有最低的機會將該dll視爲「它自己的」。 gola是爲了讓它看起來和庸醫像任何其他proc COM

重要的問題問自己是 - 爲什麼我真的需要它?如果目的是緩存,則需要使用非常不同的策略,而不是快速事件處理(在這種情況下,MSMQ將很好地服務 - 現在在WCF的保護下)。