当前位置:网站首页 > Haskell函数式编程 > 正文

udp广播模式怎么改成单播(udp广播模式怎么改成单播模式)



一、引言

站长接触 AOT 已有 3 个月之久,此前在《https://links.jianshu.com/go?to=https%3A%2F%2Fmp.weixin..com%2Fs%2Fk3xV7DmSzMcwdYzeonQXAQ》一文中就有所提及。在这段时间里,站长使用 Avalonia 开发的项目也成功完成了 AOT 发布测试。然而,这一过程并非一帆风顺。站长在项目功能完成大半部分才开始进行 AOT 测试,期间遭遇了不少问题,可谓是 “踩坑无数”。为了方便日后回顾,也为了给广大读者提供参考,在此将这段经历进行总结。

.NET AOT是将.NET代码提前编译为本机代码的技术。其优势众多,启动速度快,减少运行时资源占用,还提高安全性。AOT发布后无需再安装.NET运行时等依赖。.NET 8、9 AOT发布后,可在XP、Win7非SP1操作系统下运行。这使得应用部署更便捷,能适应更多老旧系统环境,为开发者拓展了应用场景,在性能提升的同时,也增加了系统兼容性,让.NET应用的开发和部署更具灵活性和广泛性,给用户带来更好的体验。

二、经验之谈

(一)测试策略的重要性

从项目创建伊始,就应养成良好的习惯,即只要添加了新功能或使用了较新的语法,就及时进行 AOT 发布测试。否则,问题积累到后期,解决起来会异常艰难,站长就因前期忽视了这一点,付出了惨痛的代价。无奈的解决方法是重新创建项目,然后逐个还原功能并进行 AOT 测试。经过了一周的加班AOT测试,每个 AOT 发布过程大致如下:

    经过一周的努力,项目 AOT 后功能测试终于正常,至此收工。

    (二)AOT 需要注意的点及解决方法

    1. 添加rd.xml

    在主工程创建一个XML文件,例如Roots.xml,内容大致如下:

    <linker> <assembly fullname="CodeWF.Toolbox.Desktop" preserve="All" /> </linker>

    需要支持AOT的工程,在该XML中添加一个assembly节点,fullname是程序集名称,CodeWF.Toolbox.Desktop是站长小工具的主工程名,点击查看源码。

    在主工程添加ItemGroup节点关联该XML文件:

    <ItemGroup> <TrimmerRootDescriptor Include="Roots.xml" /> </ItemGroup>

    2. Prism支持

    站长使用了Prism框架及DryIOC容器,若要支持 AOT,需要添加以下 NuGet 包:

    <PackageReference Include="Prism.Avalonia" Version="8.1.97.11073" /> <PackageReference Include="Prism.DryIoc.Avalonia" Version="8.1.97.11073" />

    rd.xml需要添加

    <assembly fullname="Prism" preserve="All" /> <assembly fullname="DryIoc" preserve="All" /> <assembly fullname="Prism.Avalonia" preserve="All" /> <assembly fullname="Prism.DryIoc.Avalonia" preserve="All" />

    3. App.config读写

    在.NET Core中使用System.Configuration.ConfigurationManager包操作App.config文件,rd.xml需添加如下内容:

    <assembly fullname="System.Configuration.ConfigurationManager" preserve="All" />

    使用Assembly.GetEntryAssembly().location失败,目前使用ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)获取的应用程序程序配置,指定路径的方式后续再研究。

    4. HttpClient使用

    rd.xml添加如下内容:

    <assembly fullname="System.Net.Http" preserve="All" />

    5. Dapper支持

    Dapper的AOT支持需要安装Dapper.AOT包,rd.xml添加如下内容:

    <assembly fullname="Dapper" preserve="All" /> <assembly fullname="Dapper.AOT" preserve="All" />

    数据库操作的方法需要添加DapperAOT特性,举例如下:

    [DapperAot] public static bool EnsureTableIsCreated() { try { using var connection = new SqliteConnection(DBConst.DBConnectionString); connection.Open(); const string sql = $@" CREATE TABLE IF NOT EXISTS {nameof(JsonPrettifyEntity)}( {nameof(JsonPrettifyEntity.IsSortKey)} Bool, {nameof(JsonPrettifyEntity.IndentSize)} INTEGER )"; using var command = new SqliteCommand(sql, connection); return command.ExecuteNonQuery() > 0; } catch (Exception ex) { return false; } }

    6. System.Text.Json

    参考JsonExtensions.cs

    序列化

    public static bool ToJson<T>(this T obj, out string? json, out string? errorMsg) { if (obj == null) { json = default; errorMsg = "Please provide object"; return false; } var options = new JsonSerializerOptions() { WriteIndented = true, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, TypeInfoResolver = new DefaultJsonTypeInfoResolver() }; try { json = JsonSerializer.Serialize(obj, options); errorMsg = default; return true; } catch (Exception ex) { json = default; errorMsg = ex.Message; return false; } }

    反序列化

    public static bool FromJson<T>(this string? json, out T? obj, out string? errorMsg) { if (string.IsNullOrWhiteSpace(json)) { obj = default; errorMsg = "Please provide json string"; return false; } try { var options = new JsonSerializerOptions() { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, TypeInfoResolver = new DefaultJsonTypeInfoResolver() }; obj = JsonSerializer.Deserialize<T>(json!, options); errorMsg = default; return true; } catch (Exception ex) { obj = default; errorMsg = ex.Message; return false; } }

    7. 反射问题

    参考项目CodeWF.NetWeaver

      public static object CreateInstance(Type type) { var itemTypes = type.GetGenericArguments(); if (typeof(IList).IsAssignableFrom(type)) { var lstType = typeof(List<>); var genericType = lstType.MakeGenericType(itemTypes.First()); return Activator.CreateInstance(genericType)!; } else { var dictType = typeof(Dictionary<,>); var genericType = dictType.MakeGenericType(itemTypes.First(), itemTypes[1]); return Activator.CreateInstance(genericType)!; } }

        // List<T> var addMethod = type.GetMethod("Add"); addMethod.Invoke(obj, new[]{ child }) // Dictionary<Key, Value> var addMethod = type.GetMethod("Add"); addMethod.Invoke(obj, new[]{ key, value })

        解决办法,转换为实现的接口调用:

        // List<T> (obj as IList).Add(child); // Dictionary<Key, Value> (obj as IDictionary)[key] = value;

          同上面Add方法反射获取Length或Count属性皆返回0,value.Property("Length", 0),封装的Property非AOT运行正确:

          public static T Property<T>(this object obj, string propertyName, T defaultValue = default) { if (obj == null) throw new ArgumentNullException(nameof(obj)); if (string.IsNullOrEmpty(propertyName)) throw new ArgumentNullException(nameof(propertyName)); var propertyInfo = obj.GetType().GetProperty(propertyName); if (propertyInfo == null) { return defaultValue; } var value = propertyInfo.GetValue(obj); try { return (T)Convert.ChangeType(value, typeof(T)); } catch (InvalidCastException) { return defaultValue; } }

          AOT成功:直接通过转换为基类型或实现的接口调用属性即可:

          // 数组 var length = ((Array)value).Length; // List<T> if (value is IList list) { var count = list.Count; } // Dictionary<key, value> if (value is IDictionary dictionary) { var count = dictionary.Count; }

          8. Windows 7支持

          如遇AOT后无法在Windows 7运行,请添加YY-Thunks包:

          <PackageReference Include="YY-Thunks" Version="1.1.4-Beta3" />

          并指定目标框架为net9.0-windows。

          9. Winform兼容XP

          如果第8条后还运行不了,请参考上一篇文章《.NET 9 AOT的突破 - 支持老旧Win7与XP环境 - 码界工坊 (dotnet9.com)》添加VC-LTL包,这里不赘述。

          10. 其他

          还有许多其他需要注意的地方,后续想起来逐渐完善本文。

          三、总结

          AOT 发布测试虽然过程中可能会遇到诸多问题,但通过及时的测试和正确的配置调整,最终能够实现项目的顺利发布。希望以上总结的经验能对大家在 AOT 使用过程中有所帮助,让大家在开发过程中少走弯路,提高项目的开发效率和质量。同时,也期待大家在实践中不断探索和总结,共同推动技术的进步和发展。

          AOT可参考项目:

            到此这篇udp广播模式怎么改成单播(udp广播模式怎么改成单播模式)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

            版权声明


            相关文章:

          • console口配置命令大全(console口连接方式)2025-03-07 17:00:09
          • 3DTiles是什么格式(3dl是什么文件格式)2025-03-07 17:00:09
          • 聚合函数为什么不允许where中(聚合函数不允许出现在什么子句中)2025-03-07 17:00:09
          • 编程入门教程在线看(编程入门基础教程)2025-03-07 17:00:09
          • 虚拟u盘是什么(虚拟u盘是什么格式的)2025-03-07 17:00:09
          • ini文件乱码加密破解(ini文件编码方式怎么改)2025-03-07 17:00:09
          • kvm虚拟化技术分类(kvm虚拟化技术的实现方式)2025-03-07 17:00:09
          • convn函数(conv函数是什么意思)2025-03-07 17:00:09
          • rm计算公式(rm计算公式的使用方法)2025-03-07 17:00:09
          • 一级学术论文格式的设置二级学术论文格式的设置示范论文(一级学术论文格式的设置二级学术论文格式的设置三级学术论文格式的设置格式论文)2025-03-07 17:00:09
          • 全屏图片