直播中
當(dāng)在Windows中啟動Notepad程序時,眾所周知程序會執(zhí)行一個包含在容器內(nèi)的進(jìn)程??梢詥佣鄠€Notepad的實例,并且每個實例都會在一個專注的進(jìn)行程運行。使用任務(wù)管理器,可以看到在系統(tǒng)中當(dāng)前運行的所有進(jìn)程的清單。
一個進(jìn)程包括可執(zhí)行從操作系統(tǒng)中保留的在內(nèi)存中的代碼和程序數(shù)據(jù)。在進(jìn)程之內(nèi)只少有一個包含在進(jìn)程之內(nèi)的正在執(zhí)行指令的線程,并且在多數(shù)情況下有多個線程。如果程序打開了任何文件或者資源,這些資源將屬于這個進(jìn)程。
一個進(jìn)程也有一個分界線。包含在進(jìn)程之內(nèi)的錯誤代碼不能在當(dāng)前進(jìn)程之外的地區(qū)腐化。在一個進(jìn)程之內(nèi)很容易通訊,但是專業(yè)技術(shù)要求一個進(jìn)程對另一個進(jìn)程通訊是必需的。每一個進(jìn)程也在一個特殊的上下文安全系統(tǒng)中運行,這個安全系統(tǒng)規(guī)定在機器和網(wǎng)絡(luò)中進(jìn)程做什么。
一個進(jìn)程是一個在Windows 操作系統(tǒng)中獨立運行的最小單位。這會給在一個單一服務(wù)器上對一大堆應(yīng)用程序的ISP提出一個問題。ISP將會分離每一個在同一個服務(wù)器上的與另一個公司的應(yīng)用程序干擾的ASP.NET應(yīng)用程序。但是相關(guān)的發(fā)射和執(zhí)行一個對成百上千的應(yīng)用程序的過程成本禁止的。
介紹應(yīng)用程序域
.NET介紹一個應(yīng)用程序域的概念,或者AppDomain像一個過程,AppDomain是既是容器又是邊界線。.NET運行時間使用AppDomain作為代碼和數(shù)據(jù)的容器,就像操作系統(tǒng)一個過程作為代碼和數(shù)據(jù)的容器一樣。當(dāng)操作系統(tǒng)使用一個過程來分離不整齊的代碼時,.NET運行時間使用一個AppDomain來分離在一個安全邊線內(nèi)的代碼。
一個AppDomain僅僅屬于一個單過程,但是單個過程能夠保持多重的AppDomain。一個Appdomain創(chuàng)建起來相對容易(與一個過程比較起來),并且與一個過程比較起來具有少的維護(hù)費用。由于這些原因,一個AppDomain是ISP(提供成千上萬的應(yīng)用程序)的很好的解決方案。每一個應(yīng)用程序可以生存在一個獨立的AppDomain之內(nèi),并且許多這樣的AppDomain可以生存于一個單一的過程(節(jié)省費用)之內(nèi)。
AppDomain
在同服務(wù)器上創(chuàng)建了兩個ASP.NET應(yīng)用程序,并且沒有任何特殊配置。會發(fā)生什么事情呢?
一個單一的ASP.NET手工進(jìn)程使ASP.NET應(yīng)用程序變成兩方面的主要程序。在Windows XP和Windows 2000中,這一程序被命名為aspnet_wp.exe,并且這一程序運行在本地的ASPNET計數(shù)器的前后安全關(guān)系中。在Windows 2003手工程序擁有w3wp.exe并且默認(rèn)運行在NETWOR SERVICE中。
一個對旬可以進(jìn)住在一個AppDomain中。每一個ASP.NET應(yīng)用程序?qū)⒕哂兴约旱囊惶兹肿兞浚篊ache,Application進(jìn)住進(jìn)同一進(jìn)程,.NET AppDomain是一個獨立的單元。如果存有共享的或靜態(tài)成員的類,并且那些類存在于兩種應(yīng)用程序之內(nèi),每一個AppDomain擁有它自己的靜態(tài)字段的備份—數(shù)據(jù)并不共享。每一個應(yīng)用程序的數(shù)據(jù)和代碼安全獨立存在并且在一邊界之內(nèi)由AppDomain提供。
為了在AppDomain之間通訊或者在AppDomain之間交換對象,需要查看在.NET中穿過邊界的通訊技術(shù),例如.NET細(xì)微的或Web 服務(wù)。
對將AppDomain作為邊界思想的警告之一是ASP.NET應(yīng)用程序在默認(rèn)情況下會帶著充分的信任運行。充分信任的代碼可以執(zhí)行本地代碼,并且本地代碼可以本質(zhì)地在進(jìn)程之內(nèi)的任何內(nèi)容。需要運行帶著部分信任執(zhí)行應(yīng)用程序來約束存取不完整的代碼并且對安全的AppDomain驗證所有代碼。
隱藏備份并且重新啟動
一旦一個集合加載到一個AppDomain,沒有辦法從AppDomain集合的辦法。不過,從一個進(jìn)程中移除一個AppDomain是有可能的。
如果將一個已更新的dll復(fù)制到一個應(yīng)用程序的子目錄中,從ASP.NET的運行時間知道有新代碼要執(zhí)行。既然ASP.NET不能將dll復(fù)制到已存在的AppDomain中,它就會起動一個新AppDomain。舊的應(yīng)用程序域是“排水已停止”,那就是,存在的需要被允許完成執(zhí)行并且一旦它們執(zhí)行完成AppDomain可以卸載。帶有新代碼的新的AppDomain就會開始并且開始所有的新請求。
典型地說,當(dāng)一個dll加載進(jìn)一個進(jìn)程時,進(jìn)程對dll加鎖并且不能對磁盤的上的文件進(jìn)行覆蓋。不過,AppDomain有一個眾所周知的特點:隱藏復(fù)制那所有的允許保留在磁盤上的那些未被加鎖的可替換的集合。
運行時間對二進(jìn)制子目錄的帶有Shadow Copy的ASP.NET進(jìn)行初始化。AppDomain將任何的加鎖之前的dll從二進(jìn)制子目錄中拷貝到一個臨時位置并且再將這些dll加載到內(nèi)存。Shadow Copy允許沒有將網(wǎng)頁在線的情況下對所有在二進(jìn)制子目錄中的任何dll進(jìn)行重寫。
熟練掌握Domain
應(yīng)用程序域替換OS進(jìn)程將為單獨的.NET結(jié)點單元。一個可理解的應(yīng)用程序域?qū)o你一個在ASP.NET應(yīng)用程序后的手工發(fā)生的概念。使用AppDomain類的CurrentDomain屬性,可以檢查關(guān)于代碼正在運行的AppDomain的屬性,包括我們在此文章中討論的Shadow Copy。