Natasha Preheating(三)
NatashaInitializer.Preheating 预热方法
首次使用Natasha时都需要进行初始化操作,其中该方法还可以加入一个回调函数作为参数,该回调函数主要作用为减少程序集引用文件的加载,可以有效的控制内存涨幅
-
通过判断Preheating方法中回调函数的第二个参数,可以有选择性的加载哪一类
// 可以通过声明哪一些包不需要引用,例如Drawing,Xml等 // 该变量的数值应该为某一部分的包,如果写System,所有包含System的都无法引用,例如System;System.Linq等 List<String> noLoadDlls = new List<String>() { "Drawing","Xml" }; // 第二个参数为系统添加的dll名称 // 当返回值为true时为排除该引用 // 当返回值为false时为添加该引用 NatashaManagement.Preheating((asName, name) => { if (!String.IsNullOrEmpty(name)) { // 判断noLoadDlls中是否存在符合参数二的数据 // 如果有则返回noLoadDlls中的数据,否则返回空字符串 // 将判断的字符串都变为小写或大写,这样就不会出现大小写判断的问题了 var bReturn = noLoadDlls.Where(dll => name.ToLower().Contains(dll.ToLower())).ToList().FirstOrDefault(""); return !String.IsNullOrEmpty(bReturn); } return false; });
-
Preheating方法中回调函数的第一个参数为AssemblyName,主要判断程序集版本号,程序集名称等
AssemblyName中的Name就是回调函数中的第二个参数,单独拿出来的目的感觉主要还是对比名称
// 排除 dapper 主版本号为 12 的程序集引用文件 NatashaInitializer.Preheating((asmName, name) => { if (asmName.Name != null) { if (asmName.Name.Contains("Dapper") && asmName.Version!.Major > 12) { return true; } } return false; });
-
Preheating主要干了什么
-
如果有回调函数,则赋值给DefaultUsing.SetDefaultUsingFilter和NatashaDomain.SetDefaultAssemblyFilter,让回调函数一直有效
-
获取所有系统引用,回调函数,判断是否有手动排除引用的
-
使用DependencyContext.Default.CompileLibraries 获取CLR中的所有库
-
其中AssemblyName.GetAssemblyName的作用为将文件转换为程序集
// DependencyContext.Default.CompileLibraries获取CLR中的所有库 IEnumerable<string>? paths = DependencyContext .Default // cl.ResolveReferencePaths 获得的应为绝对路径 .CompileLibraries.SelectMany(cl => cl.ResolveReferencePaths().Where(asmPath => { //将文件转换为程序集 var asmName = AssemblyName.GetAssemblyName(asmPath); // Preheating的回调函数 return !excludeReferencesFunc(asmName, asmName.Name); }));
-
-
将排除后的都添加到Natasha中
// 1. 通过Path.GetFileNameWithoutExtension获得文件名 // 2. 把获得的文件名与文件的绝对地址关联起来 var resolver = new PathAssemblyResolver(paths); // 检查目的而加载的 Type 对象的封闭范围 // 参见:https://learn.microsoft.com/zh-cn/dotnet/api/system.reflection.metadataloadcontext?source=recommendations&view=dotnet-plat-ext-7.0 using (var mlc = new MetadataLoadContext(resolver)) { // 并发 var result = Parallel.ForEach(paths, (path) => { Assembly assembly = mlc.LoadFromAssemblyPath(path); // 添加资源 NatashaReferenceDomain.DefaultDomain.References.AddReference(assembly.GetName(), path); DefaultUsing.AddUsingWithoutCheck(assembly); // 将该类放到缓存中 NatashaDomain.AddAssemblyToDefaultCache(assembly); }); // 如果加载项一直没完成,则一直等待中 while (!result.IsCompleted) { Thread.Sleep(100); } }
-
创建了一个Supperess为CS8019的配置实例,然后测试了一下,没问题就结束了
-
有问题,那Preheating初始化会失败
-
结束
-
-
移除了不需要的包,如果想额外的添加类或dll
// 第一个方法必不可少 NatashaInitializer.Preheating(); // 1.增加全局的 Using 引用 NatashaManagement.AddGlobalUsing("System.IO"); // 2.向全局引用中增加类型对应的元数据 // 如果需要Natasha 自动覆盖全部引用,请引入 'DotNetCore.Compile.Environment' 包. NatashaManagement.AddGlobalReference(typeof(int)); // 3.直接追加程序集到全局引用中 // path为dll文件的绝对路径 Assembly assembly = mlc.LoadFromAssemblyPath(path); NatashaReferenceDomain.DefaultDomain.References.AddReference(assembly);
分类:
C#
标签:
Source Generator
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」