Natasha v9.0 为 .NET 开发者提供 [热执行] 方案.

news/2025/2/7 18:52:36/文章来源:https://www.cnblogs.com/NMSLanX/p/18261797

项目简介

自 Natasha v9.0 发布起,我将基于 Natasha 的推出热执行方案,这项技术允许基于 控制台(Console) 和新版 Asp.net Core 架构的项目在运行中动态重编译,在不停止工程的情况下获取最新结果,以帮助技术初学者、项目初期开发人员等,进行快速实验以及试错。

为了更形象的说明 [热执行] 请看下图:
HE

热执行

以下为了更加简洁,称热执行为 [HE].
图中是 Asp.net Core 一个接口开发的案例,我更改了一个实体类的结构,并保存,可以看到接口返回了最新的实体类结构。借此简单阐述一些热执行的工作原理,文件发生变化会触发 [HE] 对项目进行热编译,开发者无论是大改还是小改,只要你的项目文件(cs) 、依赖项目、csproj 发生了变化,[HE] 就会代理整个项目并自动编译输出。对于有些老机器较慢,可能 [HE] 热编译要比 [按下F5-程序跑起来] 要快的多。

热重载与热执行

也许有人会觉得这更像一个完全体的热重载,并不是,这是与热重载完全不同的技术,[HE] 的核心技术是语法树重写与动态编译。而热重载是对 Runtime 的程序集进行热更新,热重载严重依赖 Debugger 组件,且目前从 ENC 错误代码 来看这项技术的限制还是很大的。
起初我也是闷头钻研热重载技术,但实验效果很不理想,热重载技术是一项前沿的,边界明确的技术,并不适合敞开手脚快刀阔斧的干,由于不是面对开发者,(截至2024年8月)资料也不是很多。与其死磕它,不如另辟蹊径,借助 Natasha 动态代理将项目管理起来。

指令简介

注释指令

HE 使用注释作为热代理指令,这些指令会影响语法树重建以及热编译选项,但不影响程序的发布和使用。目前具体如下:

  • 优化级别

使用 //HE:Release 指令允许在 HE 重编译时,使用 Release 模式进行编译。

  • 异步代理

当 Main 方法中有对象 A, A 需要延迟卸载,A 不干扰 new A (即全局可以不只有一个 A), 此时使用 //HE:Async 允许 HE代理 在上一次 A 对象未完全销毁时异步执行新 Main 方法。

  • Using 排除

由于开发可能会开启隐式 using, 若开启,则 HE 在代理期间,会加载所有内存中存在的命名空间,因此有概率会出现 using 二义性引用问题,使用 //HE:CS0104 可以排除干扰 using,例如 //HE:CS0104 using1;using2...

  • 动态表达式

如果您需要在 HE 代理期间动态的调试输出一些结果,且不影响程序发布,您可以使用 //DS 或 //RS 指令输出其后的表达式。例如 //DS 1+1 在 Debug 模式下输出 2. //RS a.age+b.age 在 Release 输出两个对象年龄相加。

  • 参数传递

void ProxyMainArguments() 方法将在代理执行之前执行,该方法允许开发者在动态开发中,在 HE 代理期间模拟 控制台向 main 方法中传递参数。
伪代码类似于:

public static void ProxyMainArguments()
{HEProxy.AppendArgs("123");HEProxy.AppendArgs("参数2");HEProxy.AppendArgs("abc");
}
main("123","参数2","abc");

注意:HE 每次创建新的代理都是一次全新的 main 执行过程,因此将清空 Args, 避免上一次代理干扰本次执行。

  • 仅在程序第一次运行

使用 //Once 命令允许程序仅在程序第一次开启时运行被其注释的代码,在后续的 HE 代理期间,被注释的语法节点将被剔除。

使用

目前该项目支持 .NET3.0 即以上版本,且 .NET5.0 版本以上有 Source Generator 技术加持。

无 SG 加持的版本

  1. 引入热执行包:DotNetCore.Natasha.CSharp.HotExecutor
class Program
{public static void Main(string[] args){//设置当前程序的类型 ,默认为 ConsoleHEProxy.SetProjectKind(HEProjectKind.Console);//HE 代理周期日志(如果不需要 HE 写入日志,这句就不用写了)string debugFilePath = Path.Combine(VSCSProjectInfoHelper.HEOutputPath, "Debug.txt");HEFileLogger logger = new HEFileLogger(debugFilePath);//设置信息输出方式,该方法影响 DS/RS 指令的输出方式//默认是 Console.WriteLine 方式输出HEProxy.ShowMessage = async msg => {//一些项目可能禁用控制台,那就用日志输出 HE 信息await logger.WriteUtf8FileAsync(msg);};//编译初始化选项,主要是 Natasha 的初始化操作.//Once (热编译时使用 Once 剔除被注释的语句)HEProxy.SetCompileInitAction(() => {{NatashaManagement.RegistDomainCreator<NatashaDomainCreator>();NatashaManagement.Preheating((asmName, @namespace) =>!string.IsNullOrWhiteSpace(@namespace) &&(HEProxy.IsExcluded(@namespace)),true,true);}});//开始执行动态代理.//Once (热编译时使用 Once 剔除被注释的语句)HEProxy.Run();for (int i = 0; i < args.Length; i++){Console.WriteLine(args[i]);//在 HE 代理期间输出 args 值//DS args[i]}//while 阻塞时需要指定 CancelToken ,热执行时 HE 将取消循环操作。CancellationTokenSource source = new CancellationTokenSource();//添加到 HE 中,以便下个编译时释放source.ToHotExecutor();while (!source.IsCancellationRequested){Thread.Sleep(1000);//在 HE 代理期间输出 "In while loop!"//DS "In while loop!"}for (int i = 0; i < args.Length; i++){Console.WriteLine(args[i]);}//防止 while 退出后直接关闭主线程//Once (这句 `//Once` 可以不写,HE 有针对 “Console.Read” 的末尾阻塞检测)Console.ReadKey();}//方法体中的参数操作对应 Main(string[] args) 中的 args,  //热执行时,Main 将接收到 "参数11",“参数2”,“参数23”//非必要,可以不写public static void ProxyMainArguments(){HEProxy.AppendArgs("参数11");HEProxy.AppendArgs("参数2");HEProxy.AppendArgs("参数23");}
}

这段代码是 HE 最原始的代码。

SG 加持(.NET5.0及以上版本)

SG 主要是减少了 HE 初始化的一些操作。而一些需要手动传递的 cancel/dispose 实例仍然需要手动传递给 HE。

简单案例

  1. 引入 SG 包:DotNetCore.Natasha.CSharp.HotExecutor.Wrapper
internal class Program
{static void Main(string[] args){for (int i = 0; i < args.Length; i++){//DS args[i]}//这里仍然需要手动将 canceltoken 传递给 HECancellationTokenSource source = new();source.ToHotExecutor();while (!source.IsCancellationRequested){Thread.Sleep(1000);//DS "In while loop!"}//防止 while 退出后直接关闭主线程Console.ReadKey();}public static void ProxyMainArguments(){HEProxy.AppendArgs("参数1");HEProxy.AppendArgs("参数2");HEProxy.AppendArgs("参数3");HEProxy.AppendArgs("参数4");}
}

代理新 Asp.net Core

HE 目前不能代理 MVC 项目和老版的 API 项目。

public class Program
{public static void Main(string[] args){//HE:Asyncvar builder = WebApplication.CreateBuilder(args);builder.Services.AddAuthorization();builder.Services.AddEndpointsApiExplorer();builder.Services.AddSwaggerGen();var app = builder.Build();if (app.Environment.IsDevelopment()){app.UseSwagger();app.UseSwaggerUI();}//将 APP 添加到 HE 中,以便在下一次编译中释放该对象。app.AsyncToHotExecutor();//更改以下的值,保存文件,会触发 HE 创建新的 WebApplicationBuildervar summaries = new[]{"Freezing441", "Bracing"};app.MapGet("/weatherforecast", (HttpContext httpContext) =>{var forecast = 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();return forecast;}).WithName("GetWeatherForecast");app.Run();}
}

其他项目支持

截至目前而言, HE 对 Winform 的支持不是很好,WPF 的很难代理,时间和精力有限,不会深入去研究了。

鸣谢

感谢 九哥 的支持。

结尾

遇到问题可以到 Natasha Issue 区 提出反馈。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/846036.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

cmu15545笔记-并发控制总结(Concurrency Control Summary)

目录总览ACID串行化与冲突操作隔离级别概念层级二阶段锁原理级联回滚强二阶段锁死锁检测和避免锁层级实践应用实现的隔离级别OOC原理三个阶段实现的隔离级别处理幻读MVC原理写偏差异常(Write Skew Anomaly)版本存储(Version-storage)Append OnlyTime Travel StorageDelta S…

基于Bootstrap的强大jQuery表单验证插件

预览 下载 formvalidation是一款功能非常强大的基于Bootstrap的JQUERY表单验证插件。该jQuery表单验证插件内置了16种表单验证器,你也可以通过Bootstrap Validators APIs写自己的表单验证器。该表单验证插件的可用验证器有:between:检测输入的值是否在两个指定的值之间。 c…

人员跌倒检测算法

人员跌倒检测算法利用基于YOLOv5和CNN,人员跌倒检测算法通过安装在监测区域内的摄像头对人员的行为进行检测,区分正常活动和跌倒等异常行为。一旦检测到跌倒行为,系统会立即触发报警,通过声音警报、短信通知、APP推送等多种方式发出报警通知,确保相关人员能够在第一时间知…

秒开超大文件夹:如何禁止 Windows 自动识别文件夹类型

Windows 的「自动文件类型发现」功能会分析文件夹内容,以便应用最合适的视图模板。但对于包含大量文件和文件类型复杂的超大文件夹,则会导致「文件资源管理器」的打开速度变慢。本文将教你如何关闭这一功能,以加快文件夹的加载速度。 .wwads-img img { width: 150px; margin…

垃圾分类AI视觉识别系统

垃圾分类AI视觉识别系统通过高清摄像头实时捕捉垃圾投放点,垃圾分类AI视觉识别系统通过YOLOv7算法进行图像识别,识别出垃圾乱投、垃圾箱满溢、厨余垃圾误时投放等违规行为。这种智能分析算法不仅提高了识别的准确性,还能够实时监控垃圾投放点的状态,确保垃圾分类的规范性。…

学生上课行为教学评估检测系统

学生上课行为教学评估检测系统的核心在于智能识别技术,学生上课行为教学评估检测系统能够通过人脸识别与表情识别技术,捕捉学生在课堂上的面部表情和情绪变化,从而分析学生的参与度和兴趣点。人脸考勤功能则确保了出勤率的准确性,为教学管理提供了基础数据。声纹识别技术的…

电动车戴头盔智能识别系统方案

电动车戴头盔智能识别系统方案核心在于YOLOv7算法与RNN的结合,电动车戴头盔智能识别系统方案通过部署在交通要道的实时监控摄像头捕捉画面,自动识别出画面中的电动车骑行者,判断是否佩戴了安全头盔。一旦系统检测到未佩戴安全头盔的骑行者,将立即触发报警机制。报警信号不仅…

工厂车间智能视频监控系统

工厂车间智能视频监控系统对工厂车间人员行为与着装的实时监测,工厂车间智能视频监控系统通过对摄像机画面内人员的穿戴及行为进行实时监测,包括睡岗、离岗、玩手机、抽烟、摔倒等行为,以及是否穿戴反光服、安全帽、口罩、护目镜、安全带、工服等防护设备。这种监测不仅提高…

检查棋盘方格颜色---字符串

题目 String类型解答 class Solution { public boolean checkTwoChessboards(String s, String t) { int a = (s.charAt(0) + s.charAt(1)) % 2; int b = (t.charAt(0) + t.charAt(1)) % 2; return a == b; } }

让任务动起来!看板方法彻底改变你的工作方式

在现代高效工作中,“规划意识”是每个人必备的软技能。无论是个人项目还是团队协作,合理规划不仅是完成任务的保障,更是培养全局视野的重要手段。但很多人困惑于如何培养规划意识,这里分享一个简单却深刻的方法——通过在线协作看板工具将目标“具体化”和“可视化”。 目标…

C# 如何在 PropertyGrid 中,对同一double的成员显示出不同的长度的内容?

这段时间搞东西,接触到这个,整了好几天。终于 Stackoverflow 上找到一个与我思路上一样的答案。之前用了好多遍 百度 AI 的方法都牛头不对马嘴。 看来 自己对 这一套 C# 的中的反射机制中的内容还不是太熟悉。所以摸了好久。 主要思路是这样的: PropertyGrid 可以把一个对象…

【每日一题】20241203

我觉得人活着吧,有些事儿就得逼着自己不去想。因为想了,你就感觉没法活;想活,你就不能想。【每日一题】如图所示,将物块 \(a\) 分别放入光滑的 \(A\) 轨道和 \(B\) 轨道的最高点,以零初速度滑至轨道的最低点所用时间分别为 \(t_1\) 与 \(t_2\).则已知 \(A\) 轨道与 \(B\…