.NET Core 3.0 可回收程序集加載上下文的實(shí)現(xiàn)
一、前世今生
.NET誕生以來(lái),程序集的動(dòng)態(tài)加載和卸載都是一個(gè)Hack的技術(shù),之前的NetFx都是使用AppDomain的方式去加載程序集,然而AppDomain并沒(méi)有提供直接卸載一個(gè)程序集的API,而是要卸載整個(gè)AppDomain才能卸載包含在其中的所有程序集。然而卸載整個(gè)CurrentAppDomain會(huì)使程序不能工作??赡苡腥肆肀傥鹘?jīng),創(chuàng)建別一個(gè)AppDomain來(lái)加載/卸載程序集,但是由于程序集之間是不能跨域訪問(wèn)的,也導(dǎo)致只能通過(guò)Remote Proxy的方式去訪問(wèn),這樣在類型創(chuàng)建和使用上帶來(lái)了一定的難度也是類型的繼承變得相當(dāng)復(fù)雜。
.NET Core中一直沒(méi)有AppDomain的支持。但是在.NET Core 3.0中,我最期待的一個(gè)特性就是對(duì)可收集程序集的支持(Collectible AssemblyLoadContext)。 眾所周知.NET Core中一直使用AssemblyLoadContext的API,來(lái)進(jìn)行程序集的動(dòng)態(tài)加載,但是并沒(méi)有提供Unload的方法,此次升級(jí)更新了這方面的能力。
二、AssemblyLoadContext
其實(shí)這次AssemblyLoadContext的設(shè)計(jì),我認(rèn)為更像是Java中ClassLoader的翻版,可以說(shuō)非常類似。在使用過(guò)程中自定義AssemblyLoadContext可以內(nèi)部管理其中的程序集,并對(duì)整體Context進(jìn)行Unload。使用AssemblyLoadContext也可以避免程序集名稱和版本的沖突。
三、Getting Started
.NET Core 3.0還沒(méi)有正式版,所有要使用預(yù)覽版的SDK完成以下實(shí)例。我使用的是.NET Core SDK 3.0.100-preview-009812
dotnet new globaljson --sdk-version 3.0.100-preview-009812
AssemblyLoadContext是一個(gè)抽象類的,我們需要子類化。下面顯示的是我們創(chuàng)建自定義AssemblyLoadContext的方法,實(shí)現(xiàn)一個(gè)可回收的Context需要在構(gòu)造器中指定isCollectible: true :
public class CollectibleAssemblyLoadContext : AssemblyLoadContext { public CollectibleAssemblyLoadContext() : base(isCollectible: true) { } protected override Assembly Load(AssemblyName assemblyName) { return null; } }
使用netstandard2.0創(chuàng)建一個(gè)library
using System; namespace SampleLibrary { public class SayHello { public void Hello(int iteration) { Console.WriteLine($"Hello {iteration}!"); } } }
測(cè)試Load/Unload
var context = new CollectibleAssemblyLoadContext(); var assemblyPath = Path.Combine(Directory.GetCurrentDirectory(),"SampleLibrary.dll"); using (var fs = new FileStream(assemblyPath, FileMode.Open, FileAccess.Read)) { var assembly = context.LoadFromStream(fs); var type = assembly.GetType("SampleLibrary.SayHello"); var greetMethod = type.GetMethod("Hello"); var instance = Activator.CreateInstance(type); greetMethod.Invoke(instance, new object[] { i }); } context.Unload(); GC.Collect(); GC.WaitForPendingFinalizers();
當(dāng)執(zhí)行GC收回后,加載的程序集會(huì)被完全的回收。
四、最后
GitHub:https://github.com/maxzhang1985/YOYOFx 如果覺還可以請(qǐng)Star下, 歡迎一起交流。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于.NET中:自動(dòng)將請(qǐng)求參數(shù)綁定到ASPX、ASHX和MVC的方法(菜鳥必看)
這篇文章的目的就是告訴初學(xué)者如何自動(dòng)將客戶端用AJAX發(fā)送的參數(shù)自動(dòng)綁定為強(qiáng)類型的成員屬性或方法參數(shù)2013-04-04ASP.NET操作Word的IIS權(quán)限設(shè)置
檢索 COM 類工廠中 CLSID 為 {00024500-0000-0000-C000-000000000046} 的組件時(shí)失敗,原因是出現(xiàn)以下錯(cuò)誤: 80070005。2011-02-02asp.net 身份驗(yàn)證機(jī)制實(shí)例代碼
對(duì)于ASP.NET驗(yàn)證機(jī)制在項(xiàng)目開發(fā)中運(yùn)用,會(huì)使項(xiàng)目非常方便快捷的實(shí)現(xiàn)頁(yè)面的訪問(wèn)權(quán)限問(wèn)題,而且省去了一些沒(méi)必要的安全問(wèn)題2012-06-06SQL通用存儲(chǔ)過(guò)程分頁(yè),支持多表聯(lián)合
以前用.net寫分頁(yè)存儲(chǔ)過(guò)程時(shí)老是一張表就要寫一個(gè)procedure.很忙煩.后來(lái)有空就整合了一下,做了一個(gè)通用的sql分頁(yè)存儲(chǔ),支持多表聯(lián)合查詢分頁(yè).寫的不好的地方,希望大鳥們多多指導(dǎo).使的查詢速度更快.2011-11-11詳解.Net Core 權(quán)限驗(yàn)證與授權(quán)(AuthorizeFilter、ActionFilterAttribute)
這篇文章主要介紹了.Net Core 權(quán)限驗(yàn)證與授權(quán)(AuthorizeFilter、ActionFilterAttribute),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04log4net創(chuàng)建系統(tǒng)日志的詳細(xì)步驟
log4net是.Net下一個(gè)非常優(yōu)秀的開源日志記錄組件。log4net記錄日志的功能非常強(qiáng)大。它可以將日志分不同的等級(jí),以不同的格式,輸出到不同的媒介。本文主要是簡(jiǎn)單的介紹如何在Visual Studio2010(Asp.Net Mvc3.0)中使用log4net快速創(chuàng)建系統(tǒng)日志,如何擴(kuò)展以輸出自定義字段2013-11-11