Beispiel: Problembehandlung bei dynamischer Programmierung

Hinweis

Dieses Thema bezieht sich auf die .NET Native Developer Preview, ein Vorabrelease der Software. Sie können die Vorschau von der Microsoft Connect-Website herunterladen (Registrierung erforderlich).

Nicht alle Metadatensuchefehler in Apps, die mit der .NET Native Toolkette entwickelt wurden, führen zu einer Ausnahme. Einige können sich auf unvorhersehbare Weise in einer App zeigen. Das folgende Beispiel zeigt eine Zugriffsverletzung, die durch das Verweisen auf ein Nullobjekt verursacht wurde:

Access violation - code c0000005 (first chance)
App!$3_App::Core::Util::NavigationArgs.Setup
App!$3_App::Core::Util::NavigationArgs..ctor
App!$0_App::Gibbon::Util::DesktopNavigationArgs..ctor
App!$0_App::ViewModels::DesktopAppVM.NavigateToPage
App!$3_App::Core::ViewModels::AppViewModel.NavigateToFirstPage
App!$3_App::Core::ViewModels::AppViewModel::<HandleLaunch>d__a.MoveNext
App!$43_System::Runtime::CompilerServices::AsyncMethodBuilderCore.CallMoveNext
App!System::Action.InvokeClosedStaticThunk
App!System::Action.Invoke
App!$43_System::Threading::Tasks::AwaitTaskContinuation.InvokeAction
App!$43_System::Threading::SendOrPostCallback.InvokeOpenStaticThunk
[snip]

Wir versuchen, diese Ausnahme mithilfe der dreistufigen Vorgehensweise zu behandeln, die im Abschnitt „Fehlende Metadaten manuell auflösen“ von Erste Schritte erläutert wird.

Was hat die App getan?

Zunächst muss die async-Schlüsselwortmaschinerie an der Basis des Stapels beachtet werden. Zu bestimmen, welche Aktion die App in einer async-Methode wirklich ausgeführt hat, kann problematisch sein, da der Stapel den Kontext des ursprünglichen Aufrufs verloren und den async-Code in einem anderen Thread ausgeführt hat. Allerdings können wir ableiten, dass die App versucht, die erste Seite zu laden. In der Implementierung für NavigationArgs.Setup hat der folgende Code die Zugriffsverletzung verursacht:

AppViewModel.Current.LayoutVM.PageMap

In diesem Fall war die LayoutVM-Eigenschaft für AppViewModel.CurrentNULL. Das Fehlen einiger Metadaten hat ein leicht unterschiedliches Verhalten verursacht und dazu geführt, dass eine Eigenschaft anstatt eines Sets nicht initialisiert wurde, wie die App erwartet hat. Zum Verstehen der Situation könnte es helfen, einen Haltepunkt im Code an der Stelle festzulegen, an der LayoutVM initialisiert werden sollte. Beachten Sie jedoch, dass LayoutVM's-Typ ist App.Core.ViewModels.Layout.LayoutApplicationVM. Die einzige bisher in der Datei "rd.xml" vorhandene Metadatenrichtlinnie ist:

<Namespace Name="App.ViewModels" Browse="Required Public" Dynamic="Required Public" />

Eine wahrscheinlicher Ursache für den Fehler besteht darin, dass App.Core.ViewModels.Layout.LayoutApplicationVM Metadaten fehlen, da es sich in einem anderen Namespace befindet.

In diesem Fall wurde das Problem durch Hinzufügen einer Laufzeitanweisung für App.Core.ViewModels behoben. Die Grundursache war ein API-Aufruf an die Type.GetType(String)-Methode, die NULL zurückgegeben hat. Die App hat das Problem ignoriert, bis ein Absturz aufgetreten ist.

Bei der dynamischen Programmierung empfiehlt es sich bei verwendung von Reflektions-APIs unter .NET Native, die Überladungen zu verwenden, die Type.GetType eine Ausnahme bei Einem Fehler auslösen.

Handelt es sich um einen Einzelfall?

Andere Probleme können mit App.Core.ViewModels ebenfalls auftreten. Sie müssen entscheiden, ob es sich lohnt, jede fehlende Metadaten-Ausnahme zu identifizieren und zu beheben, oder Zeit zu sparen und Anweisungen für eine größere Klasse von Typen hinzuzufügen. Hier kann das Hinzufügen von dynamic Metadaten für App.Core.ViewModels der beste Ansatz sein, wenn die resultierende Größenvergrößerung der Ausgabebinärdatei kein Problem darstellt.

Könnte der Code neu geschrieben werden?

Hätte die App typeof(LayoutApplicationVM) anstelle von Type.GetType("LayoutApplicationVM") verwendet, hätte die Toolkette browse-Metadaten beibehalten können. Jedoch wären immer noch keine invoke-Metadaten erstellt worden, was zu einer MissingMetadataException-Ausnahme beim Instanziieren des Typs geführt hätte. Um die Ausnahme zu verhindern, müssten Sie eine Laufzeitanweisung für den Namespace oder den Typ hinzufügen, der die dynamic-Richtlinie angibt. Informationen zu Laufzeitanweisungen finden Sie unter Runtime Directives (rd.xml) Configuration File Reference (Verweis auf die Konfigurationsdatei der Laufzeitanweisungen (rd.xml)).

Siehe auch