不安装运行时运行 .NET 程序 - NativeAOT

大家好,先祝大家国庆快乐 。不过大家看到这篇文章的时候估计已经过完国庆了。上一篇我们写了如何通过 SelfContained 模式发布程序(不安装运行时运行.NET程序)达到不需要在目标机器上安装 runtime 就可以运行 .NET 程序的目标 。其实除了标准的 self-contained 微软还给我们带来了 Native AOT 发布模式 。是的你没看错,通过该技术我们的 .NET 程序会直接编译为 Native 代码而不再是 IL ,程序运行的时候直接就是机器码 , 不再需要 JIT 编译 。通过 AOT 技术,我们的程序启动会变的非常快并且使用更少的内存,并且运行的时候不需要在机器上安装任何运行时 。前阶段 .NET7 发布了第一个 RC 版本 , 标志着正式版的 AOT 马上会随 .NET7 发布而到来 。所以趁着国庆赶紧体验一把 。
环境与工具【不安装运行时运行 .NET 程序 - NativeAOT】现阶段 .NET7 还在RC,所以我们选择安装 SDK 7.0.100-rc.1.22431.12 ,操作系统是 WIN10 64位,开发工具是 VS2022 17.4.0 Preview 2.1。正式版的 VS2022 是没办法选择目标框架 .NET7 的,但是其实可以手动改 csproj 文件 , 所以 VS2022 Preview 不是必须的 。
Console App我们新建一个控制台程序,目标框架选择 NET7 (如果使用正式版的 VS2022 没有办法选择 net7,可以直接编辑 csproj 文件) , 右键项目选择“编辑项目文件” , 在 PropertyGroup 节点下添加 PublishAot :
<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>Exe</OutputType><TargetFramework>net7.0</TargetFramework><ImplicitUsings>enable</ImplicitUsings><Nullable>enable</Nullable><!--aot发布--><PublishAot>true</PublishAot></PropertyGroup></Project>修改 main 方法:
Console.WriteLine("Hello, AOT!");Console.Read();使用 dotnet 命令进行发布:
dotnet publish -r win-x64 -c Release

不安装运行时运行 .NET 程序 - NativeAOT

文章插图
AOT 发布相比正常发布会慢一点,等待发布成功后,我们可以到以下目录查看 bin\Release\net7.0\win-x64\publish :
不安装运行时运行 .NET 程序 - NativeAOT

文章插图
我们可以看到生成的 exe 文件只有 3.48MB,相比普通单文件发布加裁剪过后的程序小了不少 。
不安装运行时运行 .NET 程序 - NativeAOT

文章插图
我们把这个 exe 程序复制到一台没有安装 .net 环境的服务器上,顺利运行起来了 。
ASP.NET CORE上面我们测试了一下控制台程序的 AOT 发布,相对比较简单没有什么问题 。下面让我们试试应用范围最为广泛的 ASP.NET CORE 项目 AOT 发布行不行 。新建一个 ASP.NET CORE WebApi 项目,目标框架选择 NET7。同样的操作编辑 csproj 文件,添加 PublishAot 属性:
<Project Sdk="Microsoft.NET.Sdk.Web"><PropertyGroup><TargetFramework>net7.0</TargetFramework><Nullable>enable</Nullable><ImplicitUsings>enable</ImplicitUsings><PublishAot>true</PublishAot></PropertyGroup></Project>同样使用 dotnet cli 命令进行发布:
dotnet publish -r win-x64 -c Release不同于上面控制台项目的发布,ASP.NET CORE 项目的 AOT 发布会出现很多警告信息,暂且忽略 。
不安装运行时运行 .NET 程序 - NativeAOT

文章插图
等到发布完成后,我们看到生成了一个 27MB 大小的 exe 文件 。双击运行起来 , 不得不提一句 , 这个启动速度真的是肉眼可见的快 , 双击之后瞬间就启动了 。这个就是 AOT 发布最大的优势了 。
不安装运行时运行 .NET 程序 - NativeAOT

文章插图
访问一下默认生成的那个 Action 方法:http://localhost:5000/WeatherForecast/ 成功的输出了天气信息 。
不安装运行时运行 .NET 程序 - NativeAOT

文章插图
序列化的问题以上通过简单的测试,ASP.NET CORE WebApi 项目顺利的跑起来了 ,  当然他只是一个简单的示例项目,我们生产的项目相比这些要复杂多了 。经过更深入的测试,发现现阶段 ASP.NET CORE 进行 AOT 发布后有一个比较麻烦的问题,那就是 JSON 序列化 。以下代码是默认生成的 WeatherForecastController 的 GET 方法,这个方法是个标准的同步方法,进行 AOT 发布后序列化没有任何问题 。
[HttpGet]public WeatherForecast[] Get(){return Enumerable.Range(1, 5).Select(index => new WeatherForecast{Date = DateTime.Now.AddDays(index),TemperatureC = Random.Shared.Next(-20, 55),Summary = Summaries[Random.Shared.Next(Summaries.Length)]}).ToArray();}

推荐阅读