.NET 11 Breaking Changes: was mich davon betrifft

.NET 11 Breaking Changes: was mich davon betrifft

- Matt

Vor jedem Umstieg auf eine neue .NET-Version gehe ich die offizielle Breaking-Changes-Seite durch, sortiert nach Themengebiet wie ASP.NET Core oder Kryptografie. Die Liste zu .NET 11 ist lang, und der grosse Teil betrifft mich nicht: kein MAUI-Projekt, keine .NET-Framework-Anwendung unter Linux, keine DSA-Zertifikate auf macOS. Zwei Punkte daraus habe ich bereits einzeln aufgeschrieben, die neuen Hardware-Mindestanforderungen und Runtime-native async. Hier der Rest, der bei mir tatsaechlich etwas veraendert.

Wenn der Hintergrunddienst schweigend stirbt

Wirft ein BackgroundService in seiner ExecuteAsync-Methode eine Ausnahme und steht HostOptions.BackgroundServiceExceptionBehavior auf StopHost, dem Standardwert, beendet sich der Host. Bisher schloss die Task von RunAsync, StopAsync und WaitForShutdownAsync dabei trotzdem erfolgreich ab, die Anwendung verliess sich mit Exitcode 0. Ein Prozess, der wegen eines Fehlers stirbt, aber ein Erfolgssignal meldet.

Ab .NET 11 wirft die Task die Ausnahme des Dienstes, bei mehreren betroffenen Diensten gebuendelt als AggregateException. Der Exitcode wird ungleich null. Das ist eine Verbesserung, keine Regression, aber wer sich in einem Deploy-Skript oder einer Healthcheck-Logik auf den alten Exitcode 0 verlassen hat, muss das jetzt abfangen:

try
{
    await host.RunAsync();
}
catch (Exception ex)
{
    // altes Verhalten wiederherstellen, falls noetig
}

Bei meinen eigenen Diensten im Homelab war der stille Erfolg bisher schlicht unbemerkt geblieben, weil nie ein Hintergrunddienst dauerhaft ausgefallen ist. Trotzdem lohnt der Blick in jede Watchdog-Logik, die auf Exitcodes reagiert.

Testprojekte und das verschwundene Newtonsoft.Json

Microsoft.NET.Test.SDK brachte bisher Newtonsoft.Json als transitive Abhaengigkeit mit, ohne dass ein Testprojekt das Paket selbst referenzieren musste. VSTest nutzt intern jetzt System.Text.Json statt Newtonsoft.Json, um weniger Assemblies in den Testordner zu kopieren. Wer im Testprojekt JsonConvert oder JObject verwendet hat, ohne eine eigene PackageReference einzutragen, bekommt jetzt einen Kompilierfehler statt eines stillschweigend funktionierenden Builds. Bei <ExcludeAssets>runtime</ExcludeAssets> auf eine eigene Newtonsoft-Referenz gibt es stattdessen eine FileNotFoundException zur Laufzeit.

Meine Testprojekte laufen mit MSTest und ohne direkte JSON-Abhaengigkeit, ich war also nicht betroffen. Wer aber WPF-Anwendungen testet und dabei eigene Testadapter oder Data Collector einsetzt, sollte genau die pruefen: Auch Erweiterungen, die sich bisher auf die von VSTest mitgelieferte Kopie verlassen haben, scheitern jetzt beim Laden.

DateOnly und TimeOnly: TryParse kann jetzt werfen

Der Name klingt dramatischer, als die Aenderung ist. DateOnly.TryParse und TimeOnly.TryParse liefern weiterhin false bei einem ungueltigen Datum im Eingabestring. Neu ist nur, dass ein ungueltiger DateTimeStyles-Wert oder ein kaputter Formatstring jetzt eine ArgumentException wirft statt false zurueckzugeben. Das betrifft nur Code, der DateTimeStyles dynamisch zusammensetzt oder Formatstrings aus Konfiguration liest, ohne sie vorher zu validieren. In meinem Code stehen Formatstrings als Literale im Quelltext, ich habe also nichts anpassen muessen, aber es ist der Punkt auf der Liste, bei dem man am ehesten kurz zweimal hinschaut, weil der Titel mehr verspricht, als drinsteckt.

Fuer alles Weitere lohnt sich die offizielle Liste als Checkliste pro Projekt, nicht als Ganzes von vorn bis hinten. Sie ist nach eigener Aussage von Microsoft noch nicht vollstaendig und wird laufend ergaenzt.