微軟.NET開發認證(高級篇)

微軟.NET開發認證基礎技術知識大局觀——高級篇 

摘要: 本文從實際學習知識的角度出發,講述Microsoft.NET開發認證涵蓋的基礎技術知識,這些知識是通過Asp.net、Windows Forms、WCF、WPF等開發認證的基礎。 文章分爲核心技術和高級技術兩部分。
 
概述
Microsoft.NET 認證是在.NET技術面世後微軟向軟件開發者提供的開發系列認證。本文從學習知識的角度出發講解作爲一名合格的.NET開發認證工程師需要掌握的基礎技術。雖然.NET的發行版本已經到了3.5,但CLR(Common Language Runtime)作爲.NET框架中的核心部分還處於2.0版本。因此本文提到的.NET Framework功能都基於2.0,這也符合目前各項.NET開發認證的技術要求。
 
文章的大部分內容在微軟官方教程和MSDN文檔都有體現,本文以微軟官方教程爲基礎,進行概括總結,使讀者樹立良好的.NET認證基礎技術知識大局觀。如果讀者想深入學習這些知識建議閱讀微軟官方教程和MSDN文檔。文章中所述的各項內容最終解釋權歸微軟所有。
 
高級篇內容包括:實現數據序列化、使用GDI+、實現代碼訪問安全性、實現加密解密、COM組件與.NET程序集互操作、實現服務應用程序和使用電子郵件消息、使用.NET類型元數據、創建多線程應用程序和應用程序域等八項內容。
 
1. 實現數據序列化
在開發基於分佈式架構的應用程序時,首先需要解決的問題是如何將對象或數據在若干應用程序之間傳遞,常見的做法是將對象傳輸到任何目標位置之前將其轉換爲一種適當的格式以便於在兩者之間實現通信,常見的格式包括二進制格式、自定義結構化數據和基於簡單對象訪問協議的SOAP格式。
 
序列化和反序列化。序列化是指將對象或數據轉換爲另外一種格式以便於存儲和傳輸。序列化是將對象的狀態保存到流或緩衝區的過程。反序列化是指將序列化後的數據或對象轉換回該對象尚未序列化時的原始狀態。.NET Framework提供了一些格式化類和接口用於將對象轉換爲二進制格式、SOAP格式或自定義的XML格式實現多個平臺之間數據交換。另外,.NET Framework還提供了類和接口允許用戶創建自己的格式化程序,從而將對象轉換爲某種應用程序特有的自定義格式,實現自定義的序列化和反序列化。
 
序列化的不同格式。採用二進制格式進行序列化是對象和數據在不同應用程序(域)之間存儲或傳遞的最常用方式。這些應用程序(域)可以位於同一臺計算機或者一個網絡環境中。二進制格式是一系列字節,用於表示序列化的對象或數據的原始狀態。有時,用戶可能需要在完全不同的應用程序之間傳輸數據或對象,這時,你可以通過使用Web服務在應用程序之間傳遞序列化的對象和數據。SOAP作爲一種專門的XML語法,已經成爲在Web上傳輸所有數據類型的行業標準。.NET Framework提供了BinaryFormatter類和SoapFormatter類分別支持將對象序列化爲二進制格式和SOAP格式。
 
XML 序列化和反序列化。.NET Framework提供XmlSerializer類來序列化對象,通過XmlSerializer類可將對象序列化爲XML格式或反序列化爲對象。另外,.NET Framework提供SoapFormatter類支持將對象序列化爲SOAP格式和反序列化爲對象。
 
控制XML序列化和反序列化方式。.NET Framework提供了一組XML序列化特性應用於類和類成員,從而控制XmlSerializer對類的實例進行序列化或反序列化的方式。這些特性類包括XmlAnyAttributeAttribute、XmlAnyElementAttribute、XmlArrayAttribute、 XmlArrayItemAttribute、XmlAttributeAttribute、 XmlChoiceIdentifierAttribute、XmlElementAttribute、XmlIgnoreAttribute、 XmlIncludeAttribute、XmlRootAttribute、XmlTextAttribute和XmlTypeAttribute等。另外,用戶可以使用以下的XML序列化特性來控制已編碼的SOAP序列化。這些特性包括SoapAttributeAttribute、 SoapElementAttribute、SoapEnumAttribute、 SoapIgnoreAttributeSoapIncludeAttribute和SoapTypeAttribute等。
 
處理序列化事件。.NET Framework提供了一組序列化和反序列化事件處理程序特性,以便於更靈活的控制序列化和反序列化的行爲。這些特性包括 OnSerializingAttribute、OnSerializedAttribute、OnDeserializingAttribute和 OnDeserializedAttribute。
 
實現自定義序列化類。.NET Framework在System.Runtime.Serialization命名空間提供了序列化接口,以創建自定義序列化類。這些接口包括 ISerializable、IXmlSerializable、IDeserializationCallback、IFormatter以及 IFormatterConverter。結合使用序列化類型,開發人員可以收集關於被序列化的對象的信息,這些類型包括 SerializationEntry結構、SerializationInfo類和StreamingContext結構。.NET Framework還提供了三種格式化程序類包括Formatter、FormatterConverter和FormatterServices爲將序列化的數據轉換和重新構造爲對象提供基礎。
 
管理反序列化對象。使用 ObjectManager類,可以在對象進行反序列化時對其進行跟蹤,以管理反序列化對象。在反序列化過程中,Formatter會查詢 ObjectManager實例,以確定對序列化流中對象的引用是否引用已經反序列化的對象(後向引用)或引用尚未反序列化的對象(前向引用)。 ObjectManager遵循一組規則用於指定修正的順序。
 
2. 使用GDI+
GDI 是 Windows操作系統中提供二維矢量圖形、圖像處理和版式的圖像設備接口,GDI+在 GDI的基礎上進行了改進,添加了新功能並優化現有功能。GDI+託管類和接口是.NET Framework的重要組成部分,通過使用GDI+,你可以在應用程序中加入豐富圖形來增強用戶體驗。
 
圖形設備接口(GDI+)。GDI+中的對象都爲非託管對象,佔用了大量的計算機資源,由於是非託管對象,這意味着開發人員需要編寫代碼手動釋放這些對象。.NET Framework的System.Drawing命名空間提供了非託管GDI+ API的.NET Framework包裝類庫。當託管GDI+ 對象超出範圍時,垃圾回收器將其標記爲已被釋放,但是,仍然能夠編寫代碼顯式地釋放託管和非託管GDI+對象。
 
創建GDI+繪圖圖面。Graphics類封裝一個GDI+繪圖圖面,可以在其上繪製各種圖形,如直線、矩形和文本等。Windows窗體和幾乎所有的Windows UI控件類都包含CreateGraphics方法來檢索窗體或控件對應的Graphics類的對象。另外,BufferedGraphics類表示與繪製圖面關聯的內存緩存區,通過調用BufferedGraphicsContext類的Allocate方法獲取BufferedGraphics類的對象,Allocate方法還將BufferedGraphics類的對象與繪製圖面及其矩形平面關聯。BufferedGraphicsManager類可以用來實現圖形的自定義雙緩衝,以減少或消除重繪顯示圖面時產生的閃爍,可通過其Current靜態屬性訪問當前應用程序域的主 BufferedGraphicsContext對象。
 
繪製線條。Pen類定義用於繪製直線和曲線的對象,使用Pen類可以繪製直線和曲線以構成獨立矩形和橢圓等圖形的輪廓。Pen類所繪製的每條直線的起點和終點由x和y座標表示,可以是不同寬度和不同樣式(例如實線、虛線和點線)。另外,.NET Framework提供了兩個幫助器類Pens和SystemPens,Pens類的各個靜態屬性表示標準顏色的Pen對象,而SystemPens類的各個靜態屬性表示具有系統顏色的Pen對象。
 
填充圖形對象。.NET Framework提供了Brush類的派生類來給矩形和橢圓等圖形對象填充顏色。SolidBrush類表示使用單色填充圖形對象的畫筆,TextureBrush表示使用圖像模式填充圖形對象的畫筆。另外.NET Framework提供了Brushes和SystemBrushes類來獲取Brush對象,Brushes的靜態屬性表示所有標準顏色的畫筆,SystemBrushes類的靜態屬性表示所有Windows 顯示元素顏色的畫筆。
 
爲圖形對象應用顏色。.NET Framework使用RGB的擴展實現了32位ARGB。ARGB由alpha、紅色、綠色和藍色組成。Alpha定義了由ARGB表示的顏色的透明度,Alpha值爲0時表示顏色絕對透明,爲255時表示顏色絕對不透明。.NET Framework使用顏色名稱、十六進制值和ARGB值三種方式來指定顏色。爲處理ARGB顏色.NET Framework提供了一系列類和結構。Color結構表示一種ARGB顏色,SystemColors類返回表示Windows操作系統的UI元素顏色的Color對象。ColorConverter類用於將顏色值從一種數據類型轉換爲另外一種數據類型,例如將字符串值轉換爲Color對象。 ColorTranslator類用於將ARGB轉換爲十六進制或將十六進制轉換爲ARGB。
 
繪圖表層寫入文本。.NET Framework提供了Font類用於封裝在特定設備上呈現特定字體所需的紋理和資源,以幫助你在繪製表面以各種形式寫入文本。Font類爲文本定義了一個特定格式,包括字體、字號和樣式屬性。FontFamily類定義了一組基本設計相同但樣式各異的字樣。StringFormat類定義了文本的佈局,例如對齊方式和文本方向。SystemFonts類包含一些靜態屬性返回一個表示特定WindowsUI元素的Font類的對象。 FontConverter類將Font類的對象從一種數據類型轉換爲另一種數據類型。
 
3. 實現代碼訪問安全性
.NET Framework 提供的代碼訪問安全性擴展了內置於Win32 API中的基於角色的安全性模型。基於角色的機制檢查用戶憑證並查詢訪問控制列表決定是否允許應用程序執行特定操作及訪問特定系統資源。代碼訪問安全性增加了與程序集關聯的證據,此證據可以揭示應用程序的源、編寫者以及是否已被簽名。基於證據的安全性的關鍵好處是:它可以保護想要運行不可靠代碼的受信任的用戶。通過識別程序來自一個可能不安全的源,代碼訪問安全性可以自動限制程序集權限並有效減少導致代碼被破壞的可能性。
 
代碼訪問安全性的好處。代碼訪問安全性是.NET 中的核心安全性方案,它幫助限制對重要或敏感操作和資源的訪問。當嘗試鎖定系統並保護它們免受惡意代碼襲擊時,只提供用戶和代碼執行任務所需要的最少特權。當試圖實施最少特權原則時,代碼訪問安全性可以爲你提供很大的幫助。過去,基於角色的安全系統依賴於授予用戶的權限。.NET的代碼訪問安全性的創新即可以爲代碼授予訪問權限。
 
指定代碼安全性權限的方法。指定代碼安全性權限的方法包含強制式語法和聲明式語法兩種。強制式語法要求顯式創建用於在運行時進行安全性檢查的權限對象。對只有在運行時才知道其名稱和位置的文件進行讀寫等操作時,該方法特別有用。另一種廣泛採用的語法是聲明式語法,它使用代碼特性來指定執行程序集、特定類或類中的特定方法時需要哪些權限。
 
證據。代碼訪問安全使用程序集提供的證據以及當前在計算機上實施的安全性策略來確定要授予哪些權限。證據是關於程序集的信息,用於描述程序集的表示和來源,主要有主機證據和程序集證據兩種類型。主機證據描述代碼的源並指示該代碼是否經過簽名,包括Site、URL、Zone、Application Directory、Strong Name、Publisher和Hash七種。程序集提供的證據類型可能會根據其來源不同而變化。程序集證據由程序集自身提供且必須由用戶定義。在.NET Framework中System.Security和System.Security.Policy命名空間提供IEvidenceFactory接口以及Evidence和PermissionRequestEvidence兩個主要類來管理證據。
 
安全性策略。安全性策略是指管理員通過定義並配置一組規則,以管理授予不同程序集的信任級別。這些規則使用戶可以根據程序集的位置、源或其他證據來指定信任級別。.NET安全性策略模型允許在企業、計算機、用戶和應用程序域四個不同級別上設置安全性策略。每個安全性策略都在代碼組與權限之間定義一個映射。代碼組是一個共享某個證據項的程序集集合。要成爲代碼組的成員,程序集必須與代碼組的成員條件相匹配。
 
管理安全性策略。.NET Framework提供SecurityManager類對與安全系統交互的類提供主訪問點。通過使用PolicyLevel和 PolicyStatement類來管理安全性策略;通過使用Code Group類來配置代碼組,包括UnionCodeGroup類、FirstMatchCodeGroup類、FileCodeGroup類和 NetCodeGroup類。通過使用條件類型來管理代碼組成員,包括AllMembershipCondition類、 ApplicationDirectoryMembershipCondition類、GacMembershipCondition類、 HashMembershipCondition類、PublisherMembershipCondition類、 SiteMembershipCondition類、StrongNameMembershipCondition類、 UrlMembershipCondition類和ZoneMembershipCondition類。另外.NET Framework還提供了IApplicationTrustManager 和 IMembershipCondition 接口來幫助創建自定義安全性策略類型。
 
配置代碼訪問安全性策略。配置代碼訪問安全性策略主要有兩個工具。第一個是.NET Framework配置工具,它是一個Windows應用程序,用於配置程序集緩存、遠程處理服務及代碼訪問安全性等功能。第二個是命令行工具 caspol.exe,僅用於配置代碼訪問安全策略,但它提供了比.NET Framework配置工具更多的選項,Caspol.exe還提供了一種關閉代碼訪問安全性的方法。
 
權限。權限是給予授權對資源(例如執行打開文件、寫入註冊表和執行代碼)操作的對象。權限通常存儲在名爲PermissionSet的集合類,該集合類可以保存各種類型的Permission對象。權限類型包括三種:代碼訪問權限,控制代碼可資環行的操作類型;標識權限,它們直接基於程序集所提供的證據,而非基於計算機安全性策略;基於角色的安全性權限,與其他標識權限不同,基於角色的安全性權限是基於用戶標識,而非代碼標識。
 
管理權限。權限使用三種方式。請求,通常通過使用聲明式語法爲程序集請求權限。當創建程序集時,語言編譯器將被請求的權限存儲在程序集清單中,它不能提升權限使其超出當前安全性策略級別允許的範圍。要求,與請求不同,權限要求可以出現在代碼中的任何位置且經常位於類級別和方法級別。授予,只要滿足適當的條件,即使你沒有特別請求權限,計算機上的安全性策略也會自動授予代碼權限。.NET Framework提供IPermission接口和CodeAccessPermission類以作爲定義和管理權限的基礎結構的一部分。 IPermission接口由所有預定義的Permission類實現,並保證Permission類支持在定義和操作權限時所需的基本方法和屬性。該接口還可以由用戶創建的任何自定義Permission類實現。CodeAccessPermission是抽象類,很多其他Permission類都從其繼承。CodeAccessPermission類和其繼承類一個最重要的任務是執行堆棧遍歷,以確保方法的調用方是否具有訪問資源的足夠的權限,如果無,則將引發一個安全異常。
 
訪問控制。訪問控制是指控制誰可以訪問操作系統中資源的安全性。.NET Framework提供了一些管理特定資源類型(例如文件、加密密鑰、註冊表和互斥鎖)的訪問控制的基類。這些基類是 AuthorizationRule、AuthorizationRuleCollection、AccessRule和AuditRule。這些類爲更多可以實例化的專用類提供基礎功能。
 
管理訪問控制。在.NET Framework中通過使用訪問控制列表類來管理用戶對資源的訪問。這些類都爲GenericAce類和GenericAcl類的派生類,它們是:CompoundAce、CommonAce、GenericAcl、CommonAcl、DiscretionaryAcl和SystemAcl。
 
使用資源安全類來保護資源。.NET Framework包括一組安全類,提供無需直接操作訪問控制列表 (ACL) 而控制對目錄文件對象的訪問的能力。不同於管理訪問控制列表,這些類通過分配規則來管理資源訪問,這些規則提供直接操ACL相同的等效功能,但使用起來更簡單、更安全。安全類可以處理文件、目錄、註冊表、互斥鎖和信號量,這些類都從ObjectSecurity類繼承,包括 FileSystemSecurity、FileSecurity、DirectorySecurity、RegistrySecurity、 MutexSecurity和SemaphoreSecurity。
 
管理用戶標識信息。標識和主體的概念明確地出現在.NET Framework的一些類中,這些類通常會實現IIdentity接口和IPrinicpal接口中的一個,以幫助定義它們需要支持的基本功能。 IIdentity接口爲所有的標識類型定義了基本功能,這些標識類型包括GenericIdentity、WindowsIdentity、 FormsIdentity、PassportIdentity和HttpListenerBasicIdentity。IPrincipal接口確保主體類型提供了關於標識及角色的基本功能。每個主體類型表示代碼在其下運行的安全上下文,包括用戶標識和用戶角色。管理用戶標識信息常見的方式是通過使用 GenericIdentity和GenericPrincipal類來管理用戶標識;通過使用WindowsIdentity和 WindowsPrincipal類來確定Windows用戶;通過使用IdentityReference類來收集用戶標識信息;通過使用 WindowsImpersonationContext類來臨時模擬用戶。
 
4. 實現加密解密
.NET Framework 2.0 在 1.x的基礎上提供了新的加密類型,並對支持對稱和非對稱加密以及哈希的現有類型進行重大加強,通過使用加密類型確保.NET應用程序安全通信並保護敏感數據。.NET Framework提供多個System.Securrity.Cryptography命名空間中的類來實現對稱加密算法和非對稱加密算法。
 
數據加密和解密。加密是將信息轉換爲一種隱晦或難讀的格式以保護信息的過程。解密是將隱晦格式的信息轉換爲可讀格式的過程。必須使用用來加密的密鑰來執行解密。密碼應用一個算法來達到加密信息的目的。根據加密算法所使用的密碼和管理密碼的方法可將加密算法分爲兩大類。對稱加密也稱爲私鑰加密,它使用一個必須保持私有的加密密鑰。非對稱加密也稱爲公鑰加密,它使用兩個密鑰,一個保持私有,而另一個公開。
 
對稱算法執行對稱加密。對稱加密也稱爲單密鑰或私鑰加密,因爲它使用單個私鑰來對數據進行加密和解密。對稱加密通常用於保護合作伙伴公司或幾個公司之間的通信安全。對稱加密算法比非對稱加密算法簡單,因爲對稱加密算法只適用一個密鑰。所以,對稱算法的執行速度通常比非對稱算法要快很多,但是,必須確保用於對稱加密的單個密鑰的安全。如果密鑰落入別人手中,得到密鑰的人就可利用該密鑰解密已加密的信息並閱讀這些信息。對稱算法包括DES、三重DES、RC2和Rijndael。各種對稱算法在加密數據的位強度和加密方式方面是不同的。
 
對稱算法加密類。 SymmetricAlgorithm類表示所有對稱算法的實現都必須從中繼承的抽象基類,提供了所有擴展的對稱加密類都具有的基本功能。DES、 TripleDES、RC2和Rijndael類擴展了SymmetricAlgorithm類並提供具體對稱加密功能,這些類中的每個都會被相應的 CryptoServiceProvider(CSP)類進一步擴展。CSP類是通過包裝CLR外部的非託管對象來提供加密服務的具體類。
 
非對稱類執行非對稱加密。.NET Framework 提供了密碼加密類,它們可以實現最流行的非對稱算法。.NET Framework支持的非對稱算法包括RSA算法和DSA算法。各種非對稱算法在加密數據的位強度和加密方式是不同的。
 
非對稱算法加密類。 AsymmetricAlgorithm類表示所有不對稱算法的實現都必須從中繼承的抽象基類,提供了所有擴展的非對稱加密類都具有的基本功能。RSA類和DSA類擴展了AsymmetricAlgorithm類並提供具體非對稱加密功能。每一個擴展類都會被CSP類進一步擴展。
 
使用SslStream類保護TCP/IP通信的安全。SSL用於通過Web傳輸安全消息,通過SSL可以獲得結合對稱加密和非對稱加密結合所帶來的多個好處。非對稱數據簽名使用Web服務器上的私鑰,服務器將公鑰頒發給客戶端,並由客戶端傳遞敏感數據和計算密鑰的哈希值。對稱加密對被傳遞的內容進行加密。用於SSL的密鑰由稱爲證書頒發機構(CA)的第三方頒發,該機構用於驗證Web服務器或客戶端的身份。.NET Framework提供AuthenticatedStream類和SslStream類實現服務器與客戶端之間基於SSL協議的安全通信。
 
數據哈希值計算。哈希計算的知識對於開發者完整地瞭解.NET Framework中的安全性和加密是十分關鍵的。與加密相似,哈希計算有許多用途,但是很難理解哈希算法如何更安全地傳輸密碼和信息。Windows登錄是一個典型的例子,當使用用戶名和密碼登錄Windows時,密碼本身沒有被存儲和傳遞,但是密碼的哈希值會被存儲並被傳遞用於身份驗證,避免了密碼被攔截和竊取。
 
哈希算法。哈希計算是一個與加密相似的業界支持標準。哈希是將信息轉換爲隱晦值的過程,它是單向的,不能反哈希操作。哈希計算使用一個算法將輸入值映射爲哈希值或輸入值的數字表示形式。如果給出一系列相同的輸入值,則哈希算法將總是產生相同的輸出值。.NET Framework支持MD5、SHA1和HMAC算法。HashAlgorithm類是所有加密哈希算法實現均必須從中派生的基類。該類被SHA1、 MD5、KeyedHashAlgorithm、RIPEMD160、SHA256、SHA384和SHA512類擴展。另外 KeyedHashAlgorithm類包含HMAC和MACTripleDES子類。HMAC包含HMACMD5、HMACRIPEMD160、 HMACSHA1、HMACSHA256、HMACSHA384和HMACSHA512子類。
 
加密行爲擴展。.NET Framework除提供加密類和哈希類外,還提供了其他幾種用於擴展或簡化加密行爲的類,在創建複雜加密代碼時相當有用。這些附加類提供的功能包括將加密輸出定位到流、配置參數並將其傳遞給其他加密類、生成隨機數以及保護數據和內存等。通過使用CryptoStream類和CryptoConfig類來管理配置信息;通過使用ProtectedData類和ProtectedMemory類來保護存儲在文件中和內存中的數據;通過使用 CspParameters類來自定義CSP對象的行爲;通過使用CryptoAPITransform類來修改加密信息;通過使用 RandomNumberGenerator類來爲機密函數生成強隨機函數。
 
5.COM 組件與.NET程序集互操作
託管組件和非託管組件在工作方式上存在很大差異,使得兩類組件之間不能直接通信或不能無縫的作爲同一應用程序的兩個部分來有效運行。在.NET應用程序中使用COM組件的原因有多種,最重要的是保持已有的技術投資。例如,你可能已在早期Visual Basic版本中創建了一個自定義COM組件,且未將其升級爲.NET版本,或者你需要使用COM組件來自動執行程序。不過.NET提供了優秀的解決方案來實現託管組件和非託管組件之間的交互。本節介紹如何創建與COM組件和非託管DLL通信的.NET應用程序,在.NET應用程序中使用COM組件以及設計可被COM組件調用的.NET應用程序。
 
使用Interop服務來訪問COM組件。當.NET應用程序需要使用COM組件時,必須創建一個特殊的程序集,以處理.NET代碼與COM組件之間的通信,該程序集稱爲Interop程序集,也稱爲RCW(runtime callable wrapper,運行庫可調用包裝)。Interop程序集在.NET程序集和COM組件之間提供一箇中間層,以允許兩者之間的通信。Interop程序集使COM組件表現得好像在與另一個COM組件通信,也使.NET代碼表現得好像在與另一個.NET組件通信。
 
創建Interop程序集。通過讀取COM組件中定義的類型的元數據來創建Interop程序集,並通過使用該元數據來創建.NET中的相應類,Interop程序集就可以將.NET類型轉換爲COM組件所支持的相應類型。使用Visual Studio是創建Interop程序集的最簡單方法。如果想控制創建Interop程序集的過程,則可以使用TlbImp.exe命令行工具。
 
設計與COM組件進行交互操作的.NET類型。應當專門設計.NET組件,以使其有利於與COM組件進行有效通信。要允許COM組件與.NET組件通信,必須限定與COM組件進行交互操作的.NET類型。限定與COM組件進行交互操作的.NET類型包括Classes應當顯式實現接口和設置託管類型訪問修飾符爲公共,公共類型是COM組件唯一可見的數據成員。
 
應用屬性控制COM互操作性的類型轉換。通過在.NET代碼中應用ComVisibleAttribute特性,以控制向COM組件公開.NET應用程序的方式,可以將該特性應用於類型、方法、屬性、參數以及字段。如果想對COM組件隱藏某個公共成員,則應該爲該成員添加ComVisibleAttribute特性並設置Value值爲 false。有兩類屬性可以控制.NET組件與COM組件的交互。第一類爲設計時屬性,它可以直接應用於.NET字段、屬性、方法和類。第二類爲轉換時屬性,在創建Interop程序集時,COM Interop工具使用此屬性。所有這些屬性都是System.Runtime.InteropServices命名空間的成員。
 
打包和部署程序集實現COM互操作性。在創建一個用於列出.NET程序集中所使用的所有數據類型的指定接口後,COM應用程序就可以使用.NET程序集。除這些步驟外,還必須提供程序集的部署指令幷包含一個類型庫。部署程序集時,如果將Interop程序集安裝在全局程序集緩存中以供多個應用程序使用,則必須爲程序集分配一個強名稱。如果不爲程序集分配強名稱,則只能作爲私有程序集安裝,且每個程序集需要包含一個DLL(包含.NET Interop程序集)的副本。
 
創建.NET程序集類型庫。COM組件要求在類型庫中定義該數據,因爲COM客戶端無法從程序集元數據中讀取類型信息。程序集、模塊、類型、參數和字段的表示形式,首先必須要從程序集導出到類型庫,在使用類型庫之前,必須向COM註冊它。可以使用類型庫導出工具(TlbExp.exe)、TypeLibConverter類、程序集註冊工具(RegAsm.exe)或.NET服務安裝工具(RegSvc.exe)來創建.NET程序集的類型庫。
 
平臺調用服務(Platform Invocation Service)。儘管.NET Framework類庫包含大量的類,這些類可提供應用程序要求的絕大部分功能,但有些工作卻只能通過非託管代碼來提供,例如組成Win32 API的DLL,必須使用平臺調用以在.NET應用程序中調用非託管代碼。平臺調用Win32 API是公開操作系統功能的核心接口集,它是一種服務,最常見的用途是創建包含Win32 API函數的.NET類,調用Win32 API中的函數。它允許.NET應用程序調用非託管Dll,找到並調用函數,並跨交互操作邊界封送該函數的參數。要使用平臺調用,必須找到要調用的函數和該函數所在的DLL的名稱和簽名,編寫相同簽名的託管函數,需要確保所使用的函數數據類型是正確的,還必須爲與被調用的非託管DLL中函數具有相同簽名的函數添加DllImportAttribute特性。
 
平臺調用數據封送。當從託管代碼中調用非託管函數時,必須將數據類型轉換爲適當的非託管類型。轉換數據類型和通過函數調用移動數據的過程稱爲封送處理。直接映射爲非託管類型的託管類型爲 blittable類型,那些非直接映射的稱爲non-blittable類型。在與COM通信時,如果想自定義並控制數據封送過程,則可以使用 System.Runtime.IneropServices.Marshal類來控制如何封送數據以及分配和釋放內存。Marshal類允許通過分配非託管內存、複製非託管內存塊以及將託管類型轉換爲非託管類型,以控制封送處理過程。如果想改變參數、字段或返回值的默認封送處理行爲,則可以使用 System.Runtime.InteropServices.MarshalAsAttribute特性,只有當給定類型可以封送到多個類型時才必須使用該屬性。
 
配置非託管函數。調用非託管DLL的一個重要方面就是配置函數。正確地配置完成非託管函數之後,就可以像調用其他.NET函數一樣來調用它們。但是,如果將一個結構或對象傳遞給非託管代碼,則必須提供附加信息以保存原始佈局和對齊方式,可以使用.NET Framework 中的system.Rumtime.InteropServices.StructLayoutAttribute類來提供此信息。
 
使用Exception類映射HRESULT。 COM方法通過返回HRESULT來報告錯誤,而.NET方法通過拋出異常來報告錯誤。COM Interop通過將每個異常類映射到HRESULT來處理這兩種錯誤報告方法之間的差別。每個Exception異常類都有一個HResult屬性,該屬性用於指定異常所映射到的HRESULT。從託管代碼內調用非託管函數後,應該創建一個異常類來處理任何錯誤或創建一個自定義類來處理指定的錯誤。在.NET中,你可以通過創建一個繼承自Exception類或ApplicationException類的類來創建用戶定義的異常類。要確保COM可以理解用戶定義的異常,應在自定義異常類的構造函數中設置HResult屬性。要確定HRESULT的值,可以通過 System.Runtime.InteropServices.marshal.GetHrForException方法,該方法返回異常的 HRESULT值。如果COM對象實現IErrorInfo接口,則異常將包含錯誤的所有相關詳細信息。如果它未實現此接口,則異常將只包含默認信息。
 
6. 實現服務應用程序和使用電子郵件消息
.NET Framework 通過System.ServiceProcess 命名空間提供用於實現、安裝和控制 Windows 服務應用程序的類。服務是長期運行的可執行文件,其運行沒有用戶界面。實現服務包括從 ServiceBase類繼承,也包括定義在傳入開始、停止、暫停和繼續命令時所處理的特定行爲以及定義在系統關閉時所執行的自定義行爲和操作。另外,.NET Framework還提供了允許你從服務應用程序發送電子郵件消息的類。
 
Windows 服務應用程序。Windows服務應用程序是一種長時間運行的可執行文件,可設置爲在啓動計算機時自動運行,無需用戶的干預即可運行。服務通常以 LocalService賬戶在其自己的安全性上下文中運行服務,提供與本地計算機上非特權用戶相似的權限。如果服務必須訪問遠程服務器,則該服務會向遠程服務器出示匿名憑據。使用.NET Framework可以創建Win32OwnProcess服務和Win32ShareProcess服務兩種類型的服務。 Win32OwnProcess服務可以在其自己的進程中運行,Win32ShareProcess服務可以與其他服務共享一個進程。通過檢查 System.ServiceProcess.ServiceController.ServiceType屬性確定服務的類型。
 
實現Windows服務應用程序。 System.ServiceProcess.ServiceBase類是一個Windows服務應用程序的核心類,要創建一個Windows服務應用程序,必須創建一個從ServiceBase類繼承的服務類並重寫ServiceBase類的OnStart和OnStop方法。Windows服務應用程序在其生存期中有幾種狀態,依次是安裝、加載和啓動。開始運行該應用程序之後可以將其暫停或停止。在Windows服務應用程序的Main方法中,必須創建一個服務類的實例並將其傳遞給ServiceBase類的Run方法。
 
安裝Windows服務應用程序。要安裝一個 Windows服務應用程序,需要創建一個特殊的安裝程序類。ServiceInstaller類和ServiceProcessInstaller類都是從ComponentInstaller類繼承,ServiceInstaller類用於在Windows服務應用程序中安裝一個服務,必須爲應用程序中的每一個Windows服務類創建一個ServiceInstaller類的實例,用來寫註冊表值。ServiceProcessInstaller類用於安裝Windows服務應用程序的可執行文件,設置Windows服務應用程序中所有服務公共的註冊表項值。
 
管理Windows服務應用程序。Windows 服務應用程序不提供用戶界面,可以使用服務控制管理器啓動、暫停、恢復或停止服務。如果想創建一個更友好的用戶界面來控制Windows服務應用程序,可以使用System.ServiceProcess.ServiceController類通過編程方式控制Windows服務應用程序。使用該類可以創建一個管理程序來管理Windows服務應用程序。
 
啓用自定義命令。無法通過服務控制管理器傳遞自定義命令給Windows服務應用程序。如果想讓管理工具提供更改服務狀態以外的功能,需要在Windows服務應用程序中啓用自定義命令。要做到這些,可以在服務類中重寫OnCustomCommand方法。服務有三種基本狀態:運行、已暫停和已停止。但是,服務也可以等待一個命令來繼續、暫停、啓動或停止它。在這些情況下,狀態分別是ContinuePending、PausePending、StartPending和StopPending。要確定服務的當前狀態,可以檢查服務類的Status屬性。
 
使用電子郵件。通常需要應用程序將發送電子郵件消息作爲日常數據處理的一部分。.NET Framework提供了從應用程序發送電子郵件消息功能類。通過使用MailMessage、MailAddress和 MailAddressCollection類創建電子郵件消息;通過使用MailAttachment類向電子郵件消息添加資源;通過使用 SmtpClient類發送電子郵件消息;通過使用SmtpException和SmtpFailedRecipientException類處理電子郵件異常;通過使用SendCompleteEventHandler委託來處理電子郵件完成事件。
 
7. 使用.NET類型元數據
不同於COM組件,.NET程序集通過使用元數據進行自我描述。在.NET Framework中,通過System.Reflection命名空間中的類進行運行時反射來檢索元數據。在.NET應用程序中通過使用反射以加載類型、瞭解這些類型的成員和執行代碼。
 
反射。反射是指在運行時檢查程序集清單中的元數據的功能。程序集的元數據提供程序集和程序集中所有類型(包括泛型類型)的相關信息。使用此元數據,可在運行時加載程序集並創建和調用在程序集中定義的類型實例。程序集由包含類型的模塊組成,而類型包含成員,因此,需要在創建模塊前創建程序集,在創建類型前創建模塊並在創建某些類型的成員前創建該類型。.NET Framework中的很多類使用反射來執行特定任務。例如,序列化類使用反射來確定在序列化過程哪些成員保持不變。.NET Framework提供System.Type類並在System.Reflection命名空間中提供了很多類用於執行反射。
 
使用Assembly類訪問類型元數據。.NET Framework提供了Assembly類用於在反射期間訪問程序集的元數據。可以使用Assembly類檢查尚未加載到內存中的程序集,還可以通過使用此類加載並實例化程序集及其類型。Assembly類沒有構造函數,需要使用Assembly類的某個靜態方法(比如Load、LoadFile、 LoadFrom、GetAssembly、GetCallingAssembly、GetExecutingAssembly等)來創建 Assembly類的一個實例。創建Assembly類的一個實例後,你可以通過使用該類的屬性檢索程序集的相關元素據,包括CodeBase、 FullName、GlobalAssemblyCache、ImageRuntimeVersion和Location等。Assembly類還提供了檢索包含於程序集的模塊和類型的相關信息的方法,包括GetExportedTypes、GetModules、 GetReferencedAssemblies和GetTypes等。Assembly.ReflectionOnlyLoad方法將程序集加載到反射上下文中,在反射上下文中可以檢查類型但程序集不被執行。
 
使用MemberInfo類訪問類型元數據。有時,需要訪問程序集成員的相關信息,包括其類型、方法、事件、字段和屬性。.NET Framework提供了幾個類來訪問這些成員的相關信息,所有這些類都繼承自System.Reflection.MemberInfo抽象類。 MemberInfo類具有5個子類,Type類表示類型聲明的抽象類,是可用於訪問程序集相關信息的主要類之一。它幫助你訪問程序集內部的任何泛型或非泛型類型。使用 Type 的成員獲取關於類型聲明的信息,如構造函數、方法、字段、屬性和類的事件,以及在其中部署該類的模塊和程序集。MethodBase類提供一個類的方法和構造函數的相關信息。EventInfo類幫助你訪問程序集中的事件的屬性和元數據。FieldInfo類提供字段的屬性和元數據的相關信息。 PropertyInfo類提供屬性(Property)的屬性(Attribute)和元數據的相關信息。
 
通過使用MethodBody類來檢查方法的內容。.NET Framework提供了MethodBody類和LocalVariableInfo類用於檢查方法的內容。可使用MethodBody類來訪問方法內部的元數據和MSIL(Microsoft Intermediate Language,Microsoft中間語言)代碼。可以使用LocalVariableInfo類來訪問局部變量的屬性和元數據,還可以通過讀取 MethodBody類的LocalVariables屬性檢索方法中的局部變量。
 
添加元數據自定義信息。程序集是自我描述的,在 Visual Studio項目中,可在AssemblyInfo文件中添加程序集屬性。它們提供如程序集的版本號、版權信息、標題或描述之類的詳細信息。要將這些詳細信息添加到程序集元數據,可使用程序集特性。各個程序集屬性包括AssemblyTitleAttribute、 AssemblyDescriptionAttribute、AssemblyConfigurationAttribute、 AssemblyCompanyAttribute、AssemblyProductAttribute、 AssemblyCopyrightAttribute、AssemblyTrademarkAttribute、 AssemblyCultureAttribute、AssemblyVersionAttribute和 AssemblyFileVersionAttribute等。
 
動態使用程序集。.NET Framework提供了可用於在運行時動態創建程序集的自定義類,可以保存此程序集以供再次使用。通過使用自定義類,可以創建一個在運行時生成其自身代碼的工具,通過使用此工具,可以快速創建一個應用程序。通過使用自定義類,可以在運行時動態地加載程序集,使用晚期綁定來調用動態加載程序集的代碼,提供了創建靈活的應用程序的能力。
 
動態創建程序集。可以使用 System.reflection.Emit命名空間中的生成器類在運行時動態地生成程序集和類型。.NET Framework提供了AssemblyBuilder類用於動態地創建程序集,此類繼承自Assembly類。創建動態程序集時,可通過調用 AssemblyBuilder.Save方法將它保存到磁盤。默認情況下,程序集保存爲一個DLL(dynamic link library,動態鏈接庫)。如果想將程序集保存爲可執行文件,則必須調用AssemblyBuilde類的SetEntryPoint方法以指定用作應用程序入口點的過程。
 
生成器類。創建好動態程序集之後,可以使用 System.Reflection.Emit命名空間中提供的生成器類來在運行時生成模塊、類型、構造函數、事件、字段、屬性、方法、參數、局部變量和 IL代碼,所有這些類都繼承自System.Type類。ModuleBuilder用於定義並表示模塊;EnumBuilder類用於定義並表示枚舉;TypeBuilder類用於提供一組用於在運行庫內定義類、添加方法和字段以及創建類的例程;ConstructorBuilder類用於定義類的構造函數;EventBuilder類用於定義類的事件;FiledBuilder類用於定義字段;PropertyBuilder類用於定義類中的屬性;MethodBuilder類用於表示類的方法或構造函數;ParameterBuilder類用於定義參數;GenericTypeParameterBuilder類用於爲動態定義的泛型類型與方法定義和創建泛型類型參數;LocalBuilder類用於定義方法或構造函數內的局部變量;ILGenerator類用於生成MSIL代碼。這些生成器類互相依賴,必須在創建TypeBuilder之前創建 ModuleBuilder;在創建MethodBuilder、EventBuilder或PropertyBuilder之前創建 TypeBuilder;在創建ParameterBuilder或LocalBuilder之前創建MethodeBuilder。
 
綁定。綁定是尋找與唯一指定類型相對應的實現的過程。有兩種綁定類型:早期綁定和晚期綁定。.NET同時提供了早期綁定和晚期綁定。早期綁定創建某種類型的通信信道,此信道幫助編譯器有效使用此類型。早期綁定發生在將變量聲明爲特定類型時,通過將變量聲明爲特定類型(而不是Object類型)綁定到類型庫。這甚至允許編譯器在編譯應用程序之前使用反射來驗證類型。早期綁定對象允許編譯器在應用程序執行前分配內存和執行其他優化。晚期綁定發生在直至運行時纔將變量設置爲特定類型的情況。如果將變量聲明爲 Object類型,但之後在運行時又將其設置爲一個更加特殊的對象,則可以使用晚期綁定。變量直到運行時才能知道其成員,所以不能有效的使用內存或資源。晚期綁定比早期綁定效率低但更靈活,因爲在運行前不必知道將要使用的類型。動態地加載類型時必須使用晚期綁定。
 
使用綁定類型控制成員綁定。通過使用反射可以在運行時加載程序集並調用其方法,如果直至運行時才加載類型,則必須使用晚期綁定。當在運行時動態加載類和使用晚期綁定時,必須使用BindingFlags 綁定標誌來控制綁定對象的過程,BindingFlags枚舉將控制綁定和反射搜索成員和類型的方法。這些標誌將與Type.GetMember方法和 Type.InvokeMember方法一起使用實現動態加載類的成員。要在運行時動態加載類型,可以通過使用 System.Activator.CreateInstance方法先創建動態加載類型的實例,然後通過使用Type.InvokeMember方法對該類型調用方法。
 
8. 創建多線程應用程序和應用程序域
在支持大量用戶執行多個任務的同時,將性能維持在可接受的水平並高效使用資源的能力稱爲可伸縮性。設計可伸縮應用程序是一項困難的任務,關鍵因素是並行而不是順序執行任務的能力,並且可能需要在應用程序的整個生命週期中進行調整。默認情況下.NET應用程序使用單個執行線程,但是也可以使用多個線程來並行執行多個任務。不僅高端應用程序可以通過使用多個執行線程來提高性能,即便簡單的應用程序任務也可以通過多個線程來達到此目的。
 
同步編程。應用程序可能提供可供同時執行多個任務的功能。在傳統編程中,同步編程是大多數軟件環境的默認模式,它以順序方式調用多個方法,且只有在完成前一個調用後纔可以進行下一個調用。它類似於一個隊列,其中每個任務在被處理之前都必須排隊等候。根據處理任務所需時間的不同,此同步編程方法的執行效率可能十分低。因此,爲了提高效率和縮短響應時間,可以使用單獨的線程來管理每個任務,並行執行線程。
 
進程和線程。任何應用程序在執行期間都被稱爲一個進程。進程將引用由正在執行的應用程序所使用的虛擬內存空間、系統資源和數據。處理器根據接收命令的順序依次運行由進程發出的命令。線程是一個執行單元。每個進程至少要包含一個線程。如果一個進程包含多個線程,則操作系統會根據線程的優先級爲每個獨立的線程分別分配處理器時間。對於分配給進程的資源,該進程下的每個線程都擁有訪問權,只是優先級高的線程能夠更頻繁地獲得處理器的訪問權而已。在多線程進程中,應用程序既可以創建獨立的線程來運行耗時任務,同時又可以通過主線程或其他獨立的線程來繼續發出其他命令。如果執行的線程過多,則操作系統花在切換線程上的時間會比執行某個給定線程的時間還要多,這將導致性能下降。因此,應該根據實際情況來斟酌要使用的線程數,而且要相應地測試代碼以驗證其性能。
 
管理線程。.NET Framework在System.Threading命名空間提供了一些管理線程的類,使用Thread類可以通過編程方式來控制線程的行爲。雖然在運行時可以通過“任務管理器”來設置線程的優先級,但Thread類提供的線程控制遠遠超出優先級分配,且不需要用戶干涉。另外,可以通過Thread類創建銷燬和暫停線程。創建線程的過程稱爲衍生新線程,銷燬現有線程的過程稱爲註銷或終止線程,暫停線程的過程稱爲使線程進入休眠狀態。
 
創建線程。要創建線程,用戶需要用到委託。與創建 Thread類相關聯的委託有兩個,ThreadStart和ParameterizedThreadStart。這兩個委託都指向某個方法,而該方法可用作線程的起始點。其中,ParameterizedThreadStart委託可用於傳遞一個對象,而由該對象來自定義Start方法的行爲,但 ThreadStart則無這項功能。
 
管理線程池。在需要使用大量短週期線程的情況下,比如複製或移動文件,CLR分配內存及創建線程所花費的時間可能會降低應用程序的整體性能。在這些情況下,.NET Framework提供ThreadPool類來提高性能。ThreadPool類管理一組已準備好被進程使用的線程。每個進程僅具有一個用於執行各種方法的線程池。不需要在每次啓動線程時都進行資源分配,因爲已經在池中創建了該線程,這將提高應用程序性能。
 
避免使用線程池情況。線程池不是萬能的,有時候應該避免使用線程池,不應該在以下情況下使用線程池:需要前臺線程;需要某個線程具有特定的優先級;具有可以阻塞線程一段時間的任務;線程池具有最大線程數的限制,因此線程池中的大量線程被阻止可能導致任務無法啓動;需要將某些線程放置在單線程的單元中,所有的線程池都位於多線程單元中;需要有與線程關聯的穩定標識,或需要將某個線程專用於某個任務。線程池的默認大小爲每個可用處理器25個輔助線程,因此同時啓動超過25個線程,在某個給定時間只會執行25 個線程,另外的線程會進入等待狀態。
 
異步編程。異步編程允許用戶界面快速響應用戶操作,無須等待長時間運行的進程完成,具有同步編程技術所不具備的特殊功能。通過.NET Framework,可以異步調用任何方法,其中方法調用不需要等待其餘的方法完成就可以繼續執行應用程序。只需要一個額外的線程,就可以調用.NET應用程序中的任何方法,這樣做需要創建一個委託,讓它的簽名與要調用的方法的簽名相同。委託一般會公開BeginInvoke和EndInvoke方法。可以用四種方法處理異步調用:通過從主線程調用EndInvoke方法;通過使用一個WaitHandle方法以進行信號處理;通過檢查 BeginInvoke方法所返回的對象的IsCompleted屬性;調用BeginInvoke時通過使用一個回調委託。
 
使用異步類型來管理回調方法。你可以通過使用委託來執行異步調用,從而啓動任何方法。對於每個異步調用,.NET Framework創建一個IAsyncResult類型的對象,用以管理單獨的線程並檢索異步調用的結果。在任何給定時間內都可以調用多個異步方法。異步調用適用於多數場景,例如,調用處理器密集型任務時,承載Internet上的Web服務時或同時處理多個任務時。文字處理應用程序需要將接收用戶輸入和檢查拼寫同時進行,在這種情況下,主線程可以處理用戶輸入,同時執行異步調用以檢查每個新單詞的拼寫,同時還可以使用回調委託來將拼寫錯誤的單詞用下劃線標示出來。該回調委託將使用BeginInvoke方法返回的IAsyncResult對象來檢索異步方法的結果。
 
通過異步調用遷移線程的執行上下文。線程是在一個給定的執行上下文中執行,該執行上下文包含關於線程的安全、事務、同步及線程本地上下文信息。異步調用一個方法時,因爲該方法可爲不同的線程,所以可以在不同的上下文章執行它。一些情況下,你可能需要將執行上下文從一個線程傳播到另一個線程,在.NET Framework中,可以通過ExecutionContext類來實現上下文從一個線程傳播到另一個線程。當調用線程時,可以將 ExecutionContext類和HostExecutionContext類結合使用,以模擬CLR宿主執行上下文。還可以將 ExecutionContext類和HostExecutionContextManager類結合使用以控制CLR宿主應用程序所使用的上下文。
 
使用SynchronizationContext管理異步環境。在多個線程訪問同一個資源時,可能需要某種同步機制以確保在多個線程訪問同一數據的過程中它不被錯誤的更改。保持同步的一個方法是:將同步上下文從一個調用傳播到另一個調用。SynchronizationContext類可用於驗證線程的當前同步上下文,並將此上下文傳播到一個同步或異步調用中。 SynchronizationContext類的Send和Post方法可分別用於同步和異步地調用某個方法。這兩個方法都需要一個 SendOrPostCallback類型的參數,使用此參數指向一個方法,讓該方法與調用方線程在同一同步上下文中執行。
 
應用程序域。在.NET Framework出現之前,執行中的每個應用程序都由不同的進程承載。而在應用程序運行時,承載它的進程會消耗大量內存。Web應用程序很受歡迎的原因是:單個Web服務器可以同時承載100多個應用程序。但是,如果每個應用程序都可以由屬於它自身的進程承載,那麼Web服務器將消耗掉其所有資源。爲了解決這個問題,Microsoft重新設計了進程承載.NET應用程序的方法,並提出了應用程序域。通過使用應用程序域,單個進程可用作爲多個應用程序的宿主。因此,只要在同一進程內,即使位於不同的應用程序域,應用程序之間也可以實現交互。.NET Framework在這方面提供了幾個專用類,這些類之間可以交互,且都用於控制應用程序域承載應用程序的方法。
 
應用程序域優點。應用程序域用作應用程序之間的處理隔離邊界,因爲應用程序域是進程內的邊界,所以多個應用程序能夠共享單個進程。因爲單個進程可具有多個應用程序域,所以單個宿主進程可用於運行多個應用程序,從而消耗更少的資源。此外,應用程序域中承載的應用程序也可以衍生多個線程。在同一進程的不同應用程序域內運行的應用程序彼此隔離。默認情況下,一個應用程序域中運行的應用程序無法訪問其他應用程序域的資源。應用程序彼此隔離使得一個應用程序域中運行的代碼不會影響其他應用程序域中運行的代碼,還可以控制應用程序域級別上的權限。
 
配置應用程序域。在.NET中,執行單元不再是一個進程,而是一個應用程序域。當調用.NET Framework中的可執行文件、一段非託管代碼、CLR宿主以及執行指令來創建默認應用程序域並加載所需程序集時,可以利用此基礎結構來創建多個共享同一CLR宿主的應用程序,以降低操作系統資源消耗。爲了做到這一點,你需要編寫代碼以創建應用程序域並加載程序集。在創建應用程序域時,可以創建一個 AppDomainSetup類型的對象來控制應用程序域的配置設置,這些設置將影響所有加載到該應用程序域的程序集。
 
創建應用程序域。要充分利用應用程序域,必須編寫代碼以創建應用程序域並向這些域加載程序集。只要應用程序可以同時運行、同時被加載到內存中以及能夠共享某些資源,則這樣的情況都適合使用應用程序域。如果在同一進程中運行這些應用程序,則可以節省系統資源,並降低跨應用程序調用的成本,這是因爲上下文在同一進程內流動。通過使用AppDomain類可以創建應用程序域,該類的提供 CreateDomain方法來創建一個基於現有AppDomainSetup對象的新應用程序域。在創建應用程序域後,可以使用AppDomain類的各個成員進行檢索並應用各種設置,例如應用程序域策略。
 
檢索設置應用程序域信息。在一些情況下,可能需要檢索關於現有應用程序域的信息,例如驗證程序集權限時,嚮應用程序域加載程序集之前或將數據寫入應用程序配置文件時。此時,可以使用AppDomain和 AppDomainSetup類來檢索這些信息。還可以使用這些類來檢索設置信息包括程序集是否從全局程序集緩存加載、程序集的加載目錄以及應用程序的影像複製文件位置等。
 
加載程序集到應用程序域。在某些情況下,用戶需要創建自己的應用程序域並向其中加載程序集,例如,創建承載的應用程序時、創建通過編程來卸載的工具或代碼時或創建能動態卸載或重新加載的可插接組件時。要動態加載程序集,可以使用 AppDomain類的Load方法或Assembly類的Load和LoadFrom方法。而在加載程序集後,還可以使用反射來實例化程序集中的對象。另外,還可以使用CreateInstance方法來對程序集中類的對象進行實例化。
 
卸載應用程序域。在創建應用程序域後,最終需要從內存中卸載該應用程序域以釋放資源,此時可以使用AppDomain.Unload方法來實現此功能。當卸載應用程序域時,需要釋放該應用程序域所使用的所有數據結構,並從該應用程序域移除所有加載的程序集。在卸載過程中,線程將無法訪問應用程序域中的任何數據,並可能由於嘗試卸載默認應用程序域,嘗試卸載一個已卸載的應用程序域或此時有線程無法停止執行等原因而拋出CannotUnloadAppDomainException類型的異常。
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/zhzuo/archive/2009/07/15/4351927.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章