狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

C#中Assembly是.NET框架基本構建模塊

admin
2024年9月17日 11:22 本文熱度 562

1. 什么是Assembly?

在C#中,Assembly是.NET框架的一個基本構建模塊。它可以被看作是一個包含代碼和資源的可部署單元,通常以DLL或EXE文件的形式存在。Assembly承載了以下幾個關鍵特性:

  1. 代碼封裝:Assembly將相關的代碼和資源進行封裝,是代碼邏輯和資源的集合。
  2. 版本控制:每個Assembly都有一個版本號,這對于管理應用程序的不同版本非常重要。
  3. 安全性:Assembly包含安全身份信息,例如強名稱簽名,可以確保代碼的完整性和來源。
  4. 類型信息:Assembly包含元數據,描述了其內部類型和成員,可以被其他代碼使用。
  5. 可再分發性:通過將功能模塊化,Assembly可以在不同應用程序之間共享和重用。
  6. 依賴管理:Assembly提供了依賴關系的管理,確保應用程序能夠正確加載和使用所需的組件。

Assembly分為兩種類型:

  • 私有Assembly:僅供單個應用程序使用,通常存放在應用程序的目錄中。
  • 共享Assembly:可以被多個應用程序使用,通常存放在全局程序集緩存(GAC)中。

GAC是什么?

GAC,全稱為全局程序集緩存(Global Assembly Cache),是.NET框架提供的一個用于存儲共享Assembly的特殊文件夾。GAC的主要作用是允許多個應用程序共享使用公共的Assembly,實現代碼重用和版本管理。以下是GAC的一些重要特點:

  1. 共享使用:Assembly存放在GAC中后,可以被多個應用程序引用和使用,避免了重復存儲和部署。
  2. 版本控制:GAC支持不同版本的同一個Assembly共存,這使得應用程序可以使用不同版本的組件而不產生沖突。
  3. 安全性:只有具有強名稱簽名的Assembly才能存放在GAC中,強名稱簽名確保了Assembly的唯一性和完整性。
  4. 管理工具:可以使用命令行工具如gacutil來安裝或卸載GAC中的Assembly。

2. 使用場景是什么?

Assembly在C#和.NET開發中有多種使用場景,包括:

  1. 模塊化開發:將應用程序分解為多個功能模塊,每個模塊作為一個獨立的Assembly開發和維護。
  2. 代碼重用:將通用功能封裝成Assembly,以便在不同項目中共享和重用。
  3. 插件架構:使用Assembly實現插件系統,允許動態加載和執行外部組件。
  4. 版本管理:通過Assembly的版本控制機制,支持應用程序的平滑升級和不同版本共存。
  5. 分布式應用:在分布式系統中,將不同服務或組件打包為Assembly,便于部署和管理。
  6. 安全性要求:使用強名稱簽名的Assembly,確保代碼的完整性和來源可信。
  7. 跨語言互操作:通過Assembly提供的元數據支持,允許不同.NET語言之間的互操作。

3. Assembly和AppDomain有什么區別?

在C#和.NET中,Assembly和AppDomain是兩個不同的概念,各自承擔不同的角色:

Assembly

  1. 基本構建單元:Assembly是.NET應用程序的基本構建模塊,包含代碼和資源,通常以DLL或EXE文件形式存在。

  2. 模塊化和重用:Assembly用于模塊化開發和代碼重用,可以被多個應用程序共享。

  3. 版本和安全:支持版本管理和強名稱簽名,確保代碼的完整性和來源可信。

  4. 類型信息:包含元數據,描述類型和成員信息,支持反射。

AppDomain

  1. 應用程序隔離:AppDomain是.NET中用于隔離應用程序的執行環境,提供了一個輕量級的進程內隔離機制。

  2. 安全和穩定:在不同AppDomain中運行的代碼是相互隔離的,防止錯誤和崩潰的傳播,提高應用程序的穩定性和安全性。

  3. 動態加載和卸載:允許在運行時動態加載和卸載Assembly,不需要重啟整個應用程序。

  4. 跨域通信:AppDomain之間可以通過序列化和遠程處理進行通信。

區別

  • 作用域:Assembly是代碼和資源的物理單位,而AppDomain是邏輯的執行環境。
  • 用途:Assembly用于模塊化和重用,AppDomain用于隔離和管理執行。
  • 隔離性:AppDomain提供代碼執行的隔離,而Assembly在加載后共享到AppDomain中。

4. Assembly.Load和AppDomain.Load有什么區別?

System.AppDomain 提供了 Load方法。和Assembly 的靜態Load 方法不同,AppDomaim的Load是實例方法,它允許將程序集加載到指定的AppDomain 中。該方法設計由非托管代碼調用,允許宿主將程序集“注入”特定 AppDomain 中。托管代碼的開發人員一般情況下不應調用它,因為調用 AppDomaim 的Load 方法時需要傳遞一個標識了程序集的字符串。該方法隨后會應用策略,并在一些常規位置搜索程序集。我們知道,AppDomain 關聯了一些告訴 CLR如何查找程序集的設置。為了加載這個程序集,CLR 將使用與指定AppDomain 關聯的設置,而非與發出調用之AppDomain 關聯的設置。但AppDomain 的 Load 方法會返回對程序集的引用。由于System.Assembly類不是從System.MarshalByRefObject派生的,所以程序集對象必須按值封送回發出調用的那個AppDomain。但是,現在CLR就會用發出調用的那個 AppDomain 的設置來定位并加載程序集。如果使用發出調用的那個 AppDomain 的策略和搜索位置找不到指定的程序集,就會拋出一個 FileNotFoundException。這個行為一般不是你所期望的,所以應該避免使用 AppDomain 的 Load 方法。

一臺機器可能同時存在具有相同標識的多個程序集。由于重要提示LoadFrom會在內部調用 Load,所以CLR有可能不是加載你指定的文件而是加載一個不同的文件,從而造成非預期的行為。強烈建議每次生成程序集時都更改版本號,確保每個版本都有自己的唯一性標識,確保LoadFrom方法的行為符合預期。除此之外Assembly.LoadAppDomain.Load用于加載程序集,但它們的使用場景和行為有所不同:

Assembly.Load

  1. 作用域:在當前應用程序域(AppDomain)中加載程序集。
  2. 用法:通常用于在運行時加載程序集,適用于大多數動態加載需求。
  3. 返回值:返回一個Assembly對象,表示已加載的程序集的引用。
  4. 限制:無法跨應用程序域加載程序集,僅限于當前AppDomain。

AppDomain.Load

  1. 作用域:可以在指定的應用程序域中加載程序集。
  2. 用法:常用于需要在特定AppDomain中加載程序集的場景。
  3. 返回值:同樣返回一個Assembly對象,但是在指定的AppDomain中加載。
  4. 跨域加載:允許在不同的AppDomain中加載程序集,實現更好的隔離。

區別

  • 加載位置Assembly.Load在當前AppDomain加載,而AppDomain.Load可以指定AppDomain。
  • 隔離性AppDomain.Load提供了更好的隔離,可以在不同的應用程序域中加載程序集。
  • 使用場景Assembly.Load適用于簡單的動態加載,AppDomain.Load適用于需要隔離和管理的復雜場景。

什么是System.MarshalByRefObject對象?

System.MarshalByRefObject 是 .NET 框架中的一個基類,允許對象通過引用在應用程序域(AppDomain)之間進行通信。它的主要作用是在跨域場景中支持對象的遠程訪問。

關鍵點:

  1. 應用程序域(AppDomain):
    • .NET 中的應用程序域類似于輕量級的進程,用于隔離應用程序。
    • 每個應用程序域都有自己的內存空間和資源,防止不同域之間的直接訪問。
  2. Marshal-by-Reference:
    • 默認情況下,對象在不同的應用程序域之間傳遞時是通過序列化(Marshal-by-Value)進行的。
    • 繼承自 MarshalByRefObject 的對象,可以通過引用進行傳遞,這意味著對象本身并不會被復制到目標域,而是通過代理進行訪問。
  3. 遠程通信:
    • 適用于需要在不同應用程序域或不同計算機之間進行通信的場景。
    • 典型應用包括遠程方法調用(Remoting)。
  4. 生命周期:
    • 繼承 MarshalByRefObject 的對象通常會有一個有限的生命周期,由遠程調用的服務端來管理。
    • 可以通過覆蓋 InitializeLifetimeService 方法來控制對象的生存時間。

使用場景:

  • 在分布式系統中,需要跨域或者跨進程進行通信時。
  • 需要通過遠程方法調用訪問對象時。

5. CLR為什么不提供卸載?

CLR不提供卸載單獨程序集的能力。如果 CLR 允許這樣做,那么一旦線程從某個方法返回至已卸載的一個程序集中的代碼,應用程序就會崩潰。健壯性和安全性是CLR最優先考慮的目標,如果允許應用程序以這樣的一種方式崩潰,就和它的設計初衷背道而馳了。卸載程序集必須卸載包含它的整個AppDomain。使用 ReflectionOnlyLoadFrom或ReflectionOnlyLoad 方法加載的程序集表面上是可以卸載的。畢竟,這些程序集中的代碼是不允許執行的。但CLR 一樣不允許卸載用這兩個方法加載的程序集。因為用這兩個方法加載了程序集之后,仍然可以利用反射來創建對象,以便引用這些程序集中定義的元數據。如果卸載程序集,就必須通過某種方式使這些對象失效。無論是實現的復雜性,還是執行速度,跟蹤這些對象的狀態都是得不償失的。

總結:

不提供直接卸載單個程序集的功能,主要有以下幾個原因:

  1. 內存管理復雜性:卸載單個程序集會增加內存管理的復雜性,可能導致內存泄漏或其他資源管理問題。
  2. 依賴關系:程序集之間可能存在復雜的依賴關系,卸載一個程序集可能會影響其他程序集的正常運行。
  3. 應用程序穩定性:為了確保應用程序的穩定性和一致性,CLR選擇不支持單個程序集的卸載。
  4. 替代方案:CLR提供了應用程序域(AppDomain)作為隔離和管理程序集的機制。可以卸載整個AppDomain,從而釋放相關的程序集和資源。

6. 反射的性能

太多文章講解反射的好處和使用這里就不說了直接來看缺點是什么,原因有哪些。

缺點:

  • 反射造成編譯時無法保證類型安全性。由于反射嚴重依賴字符串,所以會喪失編譯時類型安全性。例如,執行 Type.GetType(“int”);要求通過反射在程序集中查找名為“int”的類型,代碼會通過編譯,但在運行時會返回null,因為CLR只知道System.Int32不知int。
  • 反射速度慢。使用反射時,類型及其成員的名稱在編譯時未知;你要用字符電名稱標識每個類型及其成員,然后在運行時發現它們。也就是說,使用System.Reflection命名空間中的類型掃描程序集的元數據時,反射機制會不停地執行字符串搜索。通常,字符串搜索執行的是不區分大小寫的比較,這會進一步影響速度。

使用反射調用成員也會影響性能。用反射調用方法時,首先必須將實參打包(pack)成數組:在內部,反射必須將這些實參解包(unpack)到線程棧上。此外,在調用方法前,CLR 必須實參具有正確的數據類型。最后,CLR必須確保調用者有正確的安全權限來訪問被調用的成員。好上述所有原因,最好避免利用反射來訪問字段或調用方法/屬性。應該利用以下兩種技權一開發應用程序來動態發現和構造類型實例。

  • 讓類型從編譯時已知的基類型派生。在運行時構造派生類型的實例,將對它的引用放到基類型的變量中(利用轉型),再調用基類型定義的虛方法。
  • 讓類型實現編譯時已知的接口。在運行時構造類型的實例,將對它的引用放到接口類型的變量中(利用轉型),再調用接口定義的方法。

示例代碼:

using System.Diagnostics;
using System.Reflection;

namespace AssemblyDemo;

class Program
{
    static void Main(string[] args)
    {
        // 創建測試對象
        var testObject = new TestClass();

        // 測試直接調用
        Stopwatch directStopwatch = Stopwatch.StartNew();
        for (int i = 0; i < 1000000; i++)
        {
            testObject.SimpleMethod();
        }
        directStopwatch.Stop();
        Console.WriteLine($"直接調用時間: {directStopwatch.ElapsedMilliseconds} ms");

        // 獲取方法信息
        MethodInfo methodInfo = typeof(TestClass).GetMethod("SimpleMethod");

        // 測試反射調用
        Stopwatch reflectionStopwatch = Stopwatch.StartNew();
        for (int i = 0; i < 1000000; i++)
        {
            methodInfo.Invoke(testObject, null);
        }
        reflectionStopwatch.Stop();
        Console.WriteLine($"反射調用時間: {reflectionStopwatch.ElapsedMilliseconds} ms");
    }
}

class TestClass
{
    private int _counter = 0;

    public void SimpleMethod()
    {
        // 增加計數器
        _counter++;
    }
}

運行結果:

直接調用時間: 1 ms

反射調用時間: 10 ms


該文章在 2024/9/18 12:01:20 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved