Quellgenerierungsmodi in System.Text.Json

Es stehen zwei Quellgenerierungsmodi zur Verfügung: Metadatenbasiert und Serialisierungsoptimierung. In diesem Artikel werden die verschiedenen Modi beschrieben.

Informationen zur Verwendung von Quellgenerierungsmodi finden Sie unter Verwenden der Quellgenerierung in System.Text.Json.

Metadatenbasierter Modus

Sie können die Quellgenerierung verwenden, um den Prozess der Metadatensammlung von der Laufzeit in die Kompilierzeit zu verschieben. Während der Kompilierung werden die Metadaten gesammelt und Quellcodedateien generiert. Die generierten Quellcodedateien werden automatisch als integraler Bestandteil der Anwendung kompiliert. Dieses Verfahren macht die Metadatensammlung zur Laufzeit überflüssig, was die Serialisierungs- und Deserialisierungsleistung verbessert.

Die aus der Quellgenerierung resultierenden Leistungsverbesserungen können erheblich sein. Die Testergebnisse haben beispielsweise eine Reduzierung der Startzeit um bis zu 40 % oder mehr, eine Verringerung des privaten Arbeitsspeichers, eine Erhöhung der Durchsatzgeschwindigkeit (im Serialisierungsoptimierungsmodus) und eine Verringerung der App-Größe gezeigt.

Bekannte Probleme

Nur public-Eigenschaften und Felder werden in beiden Serialisierungsmodi standardmäßig unterstützt. Der Reflexionsmodus unterstützt die Verwendung von privateAccessoren, der Quellgenerierungsmodus jedoch nicht. Beispielsweise können Sie das JsonInclude-Attribut auf eine Eigenschaft anwenden, die über einen private-Setter oder -Getter verfügt, und sie wird im Reflexionsmodus serialisiert. Der Quellgenerierungsmodus unterstützt nur public- oder internal-Accessoren von public-Eigenschaften. Wenn Sie [JsonInclude] auf nicht öffentlichen Accessoren festlegen und den Quellgenerierungsmodus auswählen, wird eine NotSupportedException zur Laufzeit ausgelöst.

Nur public-Eigenschaften und Felder werden in beiden Serialisierungsmodi standardmäßig unterstützt. Der Reflexionsmodus unterstützt die Verwendung von privateprivateAccessoren, der Quellgenerierungsmodus jedoch nicht. Beispielsweise können Sie das JsonInclude-Attribut auf eine Eigenschaft oder eine Eigenschaft anwenden, die über einen private-Setter oder private-Getter verfügt, und sie wird im Reflexionsmodus serialisiert. Der Quellgenerierungsmodus unterstützt nur public- oder internal-Mitglieder und public- oder internal-Accessoren von public-Eigenschaften. Wenn Sie [JsonInclude] auf private-Mitglieder oder Accessoren festlegen und den Quellgenerierungsmodus auswählen, wird eine NotSupportedException zur Laufzeit ausgelöst.

Informationen zu anderen bekannten Problemen bei der Quellgenerierung finden Sie unter GitHub-Problemen mit dem Etikett „source-generator“ im dotnet/runtime-Repository.

Serialisierungsoptimierungsmodus (schneller Pfad)

JsonSerializer verfügt über viele Features, die die Ausgabe der Serialisierung anpassen, z. B. Schreibweise für alle Eigenschaftsnamen und Beibehalten von Verweisen. Die Unterstützung all dieser Features verursacht einen gewissen Leistungsaufwand. Die Quellgenerierung kann die Serialisierungsleistung verbessern, indem optimierter Code generiert wird, der Utf8JsonWriter direkt verwendet.

Der optimierte Code unterstützt nicht alle Serialisierungsfeatures, die JsonSerializer unterstützt. Das Serialisierungsmodul erkennt, ob der optimierte Code verwendet werden kann, und greift auf den Standardserialisierungscode zurück, wenn nicht unterstützte Optionen angegeben werden. Beispielsweise ist JsonNumberHandling.AllowReadingFromString nicht auf das Schreiben anwendbar, sodass die Angabe dieser Option nicht zu einem Rückgriff auf den Standardcode führt.

Die folgende Tabelle zeigt, welche Optionen in JsonSerializerOptions von der Serialisierung mit schnellem Pfad unterstützt werden:

Serialisierungsoption Unterstützt für schnelle Pfade
AllowTrailingCommas ✔️
Converters
DefaultBufferSize ✔️
DefaultIgnoreCondition ✔️
DictionaryKeyPolicy
Encoder
IgnoreNullValues
IgnoreReadOnlyFields ✔️
IgnoreReadOnlyProperties ✔️
IncludeFields ✔️
MaxDepth ✔️
NumberHandling
PropertyNamingPolicy ✔️
ReferenceHandler
TypeInfoResolver ✔️
WriteIndented ✔️

(Die folgenden Optionen werden nicht unterstützt, da sie nur für die Deserialisierung gelten: PropertyNameCaseInsensitive, ReadCommentHandlingund UnknownTypeHandling.)

Die folgende Tabelle zeigt, welche Attribute durch die Serialisierung mit schnellem Pfad unterstützt werden:

attribute Unterstützt für schnelle Pfade
JsonConstructorAttribute
JsonConverterAttribute
JsonDerivedTypeAttribute ✔️
JsonExtensionDataAttribute
JsonIgnoreAttribute ✔️
JsonIncludeAttribute ✔️
JsonNumberHandlingAttribute
JsonPolymorphicAttribute ✔️
JsonPropertyNameAttribute ✔️
JsonPropertyOrderAttribute ✔️
JsonRequiredAttribute ✔️

Wenn eine nicht unterstützte Option oder ein Attribut für einen Typ angegeben wird, greift das Serialisierungsmodul auf den Metadatenmodus zurück, vorausgesetzt, der Quellgenerator wurde zum Generieren von Metadaten konfiguriert. In diesem Fall wird der optimierte Code nicht beim Serialisieren dieses Typs verwendet, kann aber für andere Typen verwendet werden. Daher ist es wichtig, Leistungstests mit Ihren Optionen und Workloads durchzuführen, um zu ermitteln, wie viel Nutzen Sie tatsächlich aus dem Serialisierungsoptimierungsmodus ziehen können. Außerdem erfordert die Möglichkeit, auf JsonSerializer-Code zurückzugreifen, den Metadatensammlungsmodus. Wenn Sie nur den Serialisierungsoptimierungsmodus auswählen, tritt bei der Serialisierung möglicherweise für Typen oder Optionen, die auf JsonSerializer-Code zurückgreifen müssen, ein Fehler auf.

Siehe auch