<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
        Go to my github

      【譯】如何使庫與本機 AOT 兼容(二)

      原文 | Eric Erhardt

      翻譯 | 鄭子銘

      開放式遙測

      OpenTelemetry 是一個可觀察性框架,允許開發人員從外部了解他們的系統。它在云應用程序中很流行,并且是云原生計算基金會的一部分。 .NET OpenTelemetry 庫必須修復一些地方才能與 AOT 兼容。 open-telemetry/opentelemetry-dotnet#3429 是跟蹤必要修復的主要 GitHub 問題。

      第一個阻止該庫在本機 AOT 應用程序中使用的修復是 open-telemetry/opentelemetry-dotnet#4542。問題是使用工具無法靜態分析的值類型調用 MakeGenericType。

      當調用 RegisterSlot() 或 RegisterSlot() 時,此代碼使用反射動態填充泛型類型,然后調用 ContextSlotType 的構造函數。由于此 API 是公共的,因此可以在 ContextSlotType 上設置任何開放的通用類型。然后任何值類型都可以填充到 RegisterSlot 方法中。

      修復方法是進行一個小的重大更改,并且只接受在 ContextSlotType 上設置 2 或 3 個特定類型,這實際上是客戶使用的唯一類型。

      這些類型是硬編碼的,因此不會被刪除。現在,AOT 工具可以看到完成這項工作所需的所有代碼。

      另一個問題是如何在 ActivityInstrumentationHelper 類中使用 System.Linq.Expressions。這是使用私有反射來解決沒有公共 API 的另一種情況。 open-telemetry/opentelemetry-dotnet#4513 更改了表達式代碼以確保保留必要的屬性。

      修剪工具無法靜態確定 Expression.Property(Expression, string propertyName) 引用了哪個屬性,并且 API 已被注釋以在調用它時生成警告。相反,如果您使用重載 Expression.Property(Expression, PropertyInfo) 并以工具可以理解的方式獲取 PropertyInfo,則可以使代碼修剪兼容。

      然后使用 open-telemetry/opentelemetry-dotnet#4695 完全刪除庫中的 System.Linq.Expressions 使用。

      雖然表達式可以在本機 AOT 應用程序中使用,但當您 Lambda.Compile() 表達式時,它會使用解釋器來計算表達式。這并不理想,并且可能導致性能下降。如果可能,建議在本機 AOT 應用程序中刪除 Expression.Compile() 的使用。

      接下來是修剪警告的常見誤報案例。使用 EventSource 時,通常會將 3 個以上的原始值或不同類型的值傳遞給 WriteEvent 方法。但是,當您與原始重載不匹配時,您就會陷入使用 object[] args 作為參數的重載。由于這些值是使用反射進行序列化的,因此該 API 帶有 [RequiresUnreferencedCode] 注釋,并在調用時發出警告。打開 open-telemetry/opentelemetry-dotnet#4428 以添加這些抑制。

      這種誤報發生的頻率非常高,因此 .NET 8 中的 EventSource 中的新 API 使這種誤報幾乎完全消失。

      open-telemetry/opentelemetry-dotnet#4688 中進行了另一個簡單的修復,以使 [DynamicallyAccessedMembers] 屬性通過庫。例如:

      接下來,OpenTelemetry 中的幾個導出器使用 JSON 序列化將對象數組轉換為字符串。如前所述,在沒有 JsonTypeInfo 的情況下使用 JsonSerializer.Serialize 與修剪或 AOT 不兼容。 open-telemetry/opentelemetry-dotnet#4679 將這些位置轉換為使用 OpenTelemetry 中的 System.Text.Json 源生成器。

      internal static string JsonSerializeArrayTag(Array array)
      {
          return JsonSerializer.Serialize(array, typeof(Array), ArrayTagJsonContext.Default);
      }
      
      [JsonSerializable(typeof(Array))]
      [JsonSerializable(typeof(char))]
      [JsonSerializable(typeof(string))]
      [JsonSerializable(typeof(bool))]
      [JsonSerializable(typeof(byte))]
      [JsonSerializable(typeof(sbyte))]
      [JsonSerializable(typeof(short))]
      [JsonSerializable(typeof(ushort))]
      [JsonSerializable(typeof(int))]
      [JsonSerializable(typeof(uint))]
      [JsonSerializable(typeof(long))]
      [JsonSerializable(typeof(ulong))]
      [JsonSerializable(typeof(float))]
      [JsonSerializable(typeof(double))]
      private sealed partial class ArrayTagJsonContext : JsonSerializerContext
      {
      }
      

      現在可以在AOT應用程序中安全地使用此Jsonserializearraytag方法。請注意,它不支持任何對象序列化 - 僅支持數組和列出的原始類型。如果將不支持的對象傳遞到此方法中,則在應用程序的情況下,它將始終如一地失敗。

      更復雜的更改之一是open-telemetry/opentelemetry-dotnet#4675,它使屬性fetcher類與本機AOT兼容。顧名思義,屬性fetcher的專門設計用于從對象中檢索屬性值。它大量使用反射和制作型。因此,最終仍然用[requiensunreferencedCode]注釋。呼叫者的責任是確保手動保留必要的屬性。幸運的是,此API是內部的,因此OpenTelemetry團隊控制所有呼叫者。

      PropertyFetcher的其余問題是確保MakeErictype調用始終在本機AOT應用程序中起作用。

      這里的緩解措施利用了以下事實:如果僅使用參考類型(即類型而不是結構)調用MakeGenerictype,則.NET運行時將重用所有參考類型的相同機器代碼。

      現在,該屬性開采已更改為與本機AOT一起工作,現在可以解決的地方可以解決。 OpenTelemetry所需的方法之一是收聽診斷程序,注冊事件何時啟動的回調,然后檢查事件的“有效負載”,以記錄相應的遙測事件。有3個執行此操作并使用PropertyFetcher的儀器庫。

      前2個PR能夠抑制裝飾警告,因為基礎診斷代碼(HttpClientASP.NET Core)可確保有效載荷上的重要屬性保留在修剪和AOT應用程序中。

      對于SQL客戶端,情況并非如此。而且,由于基礎SQLCLCLIENT庫不兼容,因此決定將OpenTElemetry.SqlClient庫標記為[quiendunreferencedCode]。

      最后,open-telemetry/opentelemetry-dotnet#4859 修復了OpentElemetry.exporter.opentelemetryprotocol庫中的最后一個警告。

      這里的問題與上面 StackExchange.Redis 庫中的問題相同。此代碼對 Google.Protobuf 庫中的對象使用私有反射,并生成 DynamicMethod 以提高性能。較新版本的 Google.Protobuf 添加了 .Clear() API,這使得不再需要此私有反射。因此,修復方法很簡單,就是更新到新版本,并使用新的 API。

      dotnet/擴展

      https://github.com/dotnet/extensions 中的新 Microsoft.Extensions.* 庫填補了構建真實世界、大規模和高可用性應用程序所需的一些缺失場景。有一些庫可以增加應用程序的彈性、更深入的診斷和合規性。

      這些庫利用其他 Microsoft.Extensions.* 功能,即將 Option 對象綁定到 IConfiguration 并使用 System.ComponentModel.DataAnnotations 屬性驗證 Option 對象。傳統上,這兩個功能都使用無界反射來獲取和設置 Option 對象的屬性,這與修剪不兼容。為了允許在精簡的應用程序中使用這些功能,.NET 8 添加了兩個新的 Roslyn 源生成器。

      dotnet/extensions 庫的初始提交已經使用了選項驗證源生成器。要使用此源生成器,您需要創建一個實現 IValidateOptions 的分部類并應用 [OptionsValidator] 屬性。

      [OptionsValidator]
      internal sealed partial class HttpStandardResilienceOptionsValidator : IValidateOptions<HttpStandardResilienceOptions>
      {
      }
      

      源生成器將在構建時檢查 HttpStandardResilienceOptions 類型的所有屬性,查找 System.ComponentModel.DataAnnotations 屬性。對于它找到的每個屬性,它都會生成代碼來驗證屬性的值是否可接受。

      然后可以使用依賴項注入 (DI) 注冊驗證器,以將其添加到應用程序中的服務中。

      在這種情況下,驗證器被注冊為在應用程序啟動時立即執行,而不是在第一次使用 HttpStandardResilienceOptions 時執行。這有助于在網站接受流量之前發現配置問題。它還確保第一個請求不需要產生此驗證的成本。

      dotnet/extensions#4625 為 dotnet/extensions 庫啟用了配置綁定程序源生成器,并修復了另一個小 AOT 問題。

      要啟用配置聯編程序源生成器,可以在項目中設置一個簡單的 MSBuild 屬性:

      <PropertyGroup>
        <EnableConfigurationBindingGenerator>true</EnableConfigurationBindingGenerator>
      </PropertyGroup>
      

      啟用后,此源生成器會查找對 Microsoft.Extensions.Configuration.ConfigurationBinder 的所有調用,并生成用于根據 IConfiguration 值設置屬性的代碼,因此不再需要反射。調用將重新路由到生成的代碼,并且不需要修改現有代碼。這允許綁定在修剪的應用程序中工作,因為每個屬性都是由代碼顯式設置的,因此它們不會被修剪。

      最后,一些代碼檢查枚舉的所有值。在 .NET 的早期版本中,執行此操作的方法是調用 Enum.GetValues(typeof(MyEnum))。但是,該 API 與 AOT 不兼容,因為需要在運行時創建 MyEnum 數組,并且 AOT 代碼可能不包含 MyEnum[] 的特定代碼。

      修復方法是在支持它的目標框架上運行時利用相對較新的 API:Enum.GetValues()。此 API 確保生成 TEnum[] 代碼。當不在新的 .NET 目標框架上時,代碼將繼續使用舊的 API。

      Dapper

      Dapper 是一個簡單的微型 ORM,用于簡化 ADO.NET 的使用。它的工作原理是在運行時基于所使用的 ADO.NET 庫(例如 Microsoft.Data.SqlClient 或 Npgsql)以及應用程序中使用的強類型(客戶、訂單等)生成動態 IL。這可以減少鍋爐的工作量-應用程序中將對象讀/寫到數據庫所需的板代碼。

      有時,您的庫中只有少數 API 與本機 AOT 不兼容。您可以將它們歸為此類,并添加專為 AOT 兼容性而設計的新 API。但就 Dapper 而言,其核心設計本質上與原生 AOT 不兼容。在運行時生成 IL 與使用原生 AOT 的原因完全相反。因此,Dapper 無法修改以支持本機 AOT。

      但它支持的場景仍然很重要,并且使用 Dapper 的開發人員體驗比使用純 ADO.NET API 好得多。為了實現這種體驗,需要新的設計。

      輸入 Dapper.AOT,它是 Dapper 的重寫版本,它在構建時生成 ADO.NET 代碼,而不是在運行時動態生成 IL。在與本機 AOT 兼容的同時,這還減少了非 AOT 應用程序的啟動時間,因為代碼已經生成并編譯,無需在應用程序啟動時生成它。

      深入探討這是如何實現的,值得單獨寫一篇博客文章,并且您可以在文檔中找到簡短的解釋。如果您發現自己需要完全重寫庫才能使用 Roslyn 源生成器,請查看源生成器入門文檔。盡管開發成本高昂,但源生成器可以消除使用無界反射或在運行時生成 IL 的必要性。

      從不支持原生 AOT

      有些 .NET 代碼永遠不會支持本機 AOT。庫可能存在本質上的基本設計,使其不可能兼容。一個例子是可擴展性框架,例如托管可擴展性框架。該庫的全部目的是在運行時加載原始可執行文件不知道的擴展。這就是 Visual Studio 的可擴展性的構建方式。您可以為 Visual Studio 構建插件來擴展其功能。此場景不適用于本機 AOT,因為擴展可能需要從原始應用程序中刪除的方法(例如 string.Replace)。

      Newtonsoft.Json 屬于庫可能決定不支持本機 AOT 的另一種情況。圖書館需要考慮現有客戶。如果不進行重大更改,使現有 API 兼容可能是不可行的。這也將是一項相當大的工作量。在這種情況下,有一個已經兼容的替代方案。所以這里的好處可能不值得付出代價。

      開誠布公地告訴客戶您的目標和計劃對客戶很有幫助。這樣客戶就可以了解他們的應用程序和庫并為其制定計劃。如果您不打算在圖書館中支持本機 AOT,請告訴客戶,讓他們知道制定替代計劃。如果這需要大量工作,但最終可能會發生,那么了解這些信息也很有幫助。在我看來,有效的溝通是軟件開發中最有價值的特質之一。

      概括

      Native AOT正在擴展.NET可以成功使用的場景。與傳統的獨立 .NET 應用程序相比,應用程序可以更快地啟動,使用更少的內存,并且磁盤大小更小。但為了讓應用程序使用這種新的部署模型,它們使用的庫需要與本機 AOT 兼容。

      我希望您發現本指南有助于使您的庫與本機 AOT 兼容。

      原文鏈接

      How to make libraries compatible with native AOT

      知識共享許可協議

      本作品采用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。

      歡迎轉載、使用、重新發布,但務必保留文章署名 鄭子銘 (包含鏈接: http://www.rzrgm.cn/MingsonZheng/ ),不得用于商業目的,基于本文修改后的作品務必以相同的許可發布。

      如有任何疑問,請與我聯系 (MingsonZheng@outlook.com)

      posted @ 2024-02-17 11:01  鄭子銘  閱讀(476)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 河津市| 亚洲精品色无码AV试看| 日韩欧美在线综合网另类| 亚洲成人av综合一区| 国产日女人视频在线观看| 老熟妇欲乱一区二区三区| av大片| 日本福利一区二区精品| 国产成人无码| 天天爽夜夜爱| 午夜性刺激在线观看| 久久国产精品老人性| 久久热这里只有精品最新| 综1合AV在线播放| 云梦县| 国产av综合影院| 无码福利写真片视频在线播放| 中文字幕人妻无码一区二区三区 | 国产线播放免费人成视频播放| 久久婷婷五月综合色精品| 大乳丰满人妻中文字幕日本| 国产午夜福利高清在线观看| 内地自拍三级在线观看| 亚洲国产精品午夜福利| 亚洲老熟女一区二区三区| 亚洲国产欧美一区二区好看电影| 久久中文字幕无码专区| 老熟女熟妇一区二区三区| 美女无遮挡免费视频网站| 亚洲女同精品久久女同| 思思热在线视频精品| 一个色综合亚洲热色综合| 亚洲男人天堂av在线| 久久蜜臀av一区三区| 欧美人成在线播放网站免费| 国产亚洲综合欧美视频| 嘉荫县| 又大又粗欧美成人网站| 青青草无码免费一二三区| 国产爆乳无码av在线播放| 国产一区二区在线激情往|