.NET Core 3.0 的 ReadyToRun

.NET Core 從2016 年發展至今四年了,前陣子的.NET Core 3.0補上了Windows Forms、WPF桌面應用程式支援,讓其應用範圍擴及桌面應用程式,接著的preview 6 則帶來了ReadyToRun的部署模式,這是一個類似.NET Framework NGEN的技術,用來加快.NET Core應用程式的啟動效能,結合preview 5的單一執行檔模式,可以編譯出單一執行檔,又有更好啟動速度的.NET Core 3.0 程式。

測試

  先從Preview 5 的單一執行檔模式開始,要使用這個模式,需要手動調整.csproj,加入以下定義(此處以Console 應用程式為主):

<PropertyGroup>

    <OutputType>Exe</OutputType>

    <TargetFramework>netcoreapp3.0</TargetFramework>

    <PublishSingleFile>true</PublishSingleFile>

    <RuntimeIdentifier>win-x64</RuntimeIdentifier>

</PropertyGroup>

 

完成後可以切換到專案目錄使用dotnet 命令列來發行:

dotnet publish -c release

或者是透過Visual Studio 2019的Publish功能。

便可得到單一執行檔的結果。

這是一個封裝了完整.NET Core Runtime跟程式的執行檔,也就是說目標電腦不需要安裝.NET Core就可以執行這個應用程式,啟用Assembly Trimmer功能可以把這個檔案變得更小,Assembly Trimmer會透過IL Linker只取出需要的部分。

<PropertyGroup>

    <OutputType>Exe</OutputType>

    <TargetFramework>netcoreapp3.0</TargetFramework>

    <PublishSingleFile>true</PublishSingleFile>

    <RuntimeIdentifier>win-x64</RuntimeIdentifier>

    <PublishTrimmed>true</PublishTrimmed>

</PropertyGroup>

檔案會縮小至29 MB左右。

更進一步

  為了在沒有安裝.NET Framework或.NET Core的電腦上執行,這個檔案必然是一個原生的執行檔,這也意味著無法使用Reflector或是其他反組譯工具查看內容。

其實這個檔案內容也包含了IL Code,簡單的說就是一個原生執行檔加上.NET Assemblys封裝的,在程式執行時會把封裝在裡面的.NET Core Runtime跟我們的程式解壓到暫存目錄中後載入執行。

 

ReadyToRun

  Preview 6加上了ReadyToRun選項,可以進一步加快應用程式的載入速度,單一執行檔封裝、Assembly Trimmer、ReadyToRun是三個可以獨立也可以合併使用的選項,開啟單一執行檔封裝可以產出獨立不需要事先安裝.NET Core的應用程式,啟用Assembly Trimmer可以進一步縮小檔案大小,啟用ReadyToRun可以加快應用程式的載入速度(透過類似於NGEN技術)。

<PropertyGroup>

    <OutputType>Exe</OutputType>

    <TargetFramework>netcoreapp3.0</TargetFramework>

    <PublishSingleFile>true</PublishSingleFile>

    <RuntimeIdentifier>win-x64</RuntimeIdentifier>

    <PublishReadyToRun>true</PublishReadyToRun>

    <PublishTrimmed>true</PublishTrimmed>

</PropertyGroup>

有沒有啟用ReadyToRun差別只在於產出的.dll 是否以類似NGEN的技術執行,本質上它們還是 IL Code,還是可以透過Reflector等反組譯工具查看,這跟CoreRT是完全不同的東西喔。

參考資料

https://www.hanselman.com/blog/MakingATinyNETCore30EntirelySelfcontainedSingleExecutable.aspx

https://github.com/dotnet/coreclr/blob/master/Documentation/botr/readytorun-overview.md