Freigeben über


Migrieren Ihrer Windows 8.x-App zu .NET Native

.NET Native stellt eine statische Kompilierung von Apps im Microsoft Store oder auf dem Computer des Entwicklers bereit. Dies unterscheidet sich von der dynamischen Kompilierung, die für Windows 8.x-Apps (auch als Microsoft Store-Apps bezeichnet) vom Just-in-Time-Compiler (JIT) oder vom Native Image Generator (Ngen.exe) auf dem Gerät ausgeführt wird. Trotz der Unterschiede versucht .NET Native, die Kompatibilität mit .NET für Windows 8.x-Apps aufrechtzuerhalten. In den meisten Fällen funktionieren die Funktionen von .NET für Windows 8.x-Apps auch mit .NET Native. In einigen Fällen können jedoch Verhaltensänderungen auftreten. In diesem Dokument werden diese Unterschiede zwischen den standardmäßigen .NET für Windows 8.x-Apps und .NET Native in den folgenden Bereichen erläutert:

Allgemeine Laufzeitunterschiede

  • Ausnahmen, z TypeLoadException. B. die vom JIT-Compiler ausgelöst werden, wenn eine App auf der Common Language Runtime (CLR) ausgeführt wird, führen in der Regel zu Kompilierungsfehlern, wenn sie von .NET Native verarbeitet werden.

  • Rufen Sie die GC.WaitForPendingFinalizers -Methode nicht vom UI-Thread einer Anwendung auf. Dies kann zu einem Deadlock auf .NET Native führen.

  • Verlassen Sie sich nicht auf die Aufrufreihenfolge des statischen Klassenkonstruktors. In .NET Native unterscheidet sich die Aufrufreihenfolge von der Reihenfolge in der Standardlaufzeit. (Auch mit der Standardlaufzeit sollten Sie sich nicht auf die Reihenfolge der Ausführung der statischen Klassenkonstruktoren verlassen.)

  • Endlosschleifen ohne einen Anruf (z. B. while(true);) auf einem beliebigen Thread kann die App zum Stillstand bringen. Auf ähnliche Weise können lange oder unendliche Wartezeiten die Anwendung zum Stillstand bringen.

  • Bestimmte generische Initialisierungszyklen lösen keine Ausnahmen in .NET Native aus. Das folgende Codebeispiel löst eine TypeLoadException -Ausnahme auf der Standard-CLR aus. In .NET Native ist dies nicht der Fehler.

    using System;
    
    struct N<T> {}
    struct X { N<X> x; }
    
    public class Example
    {
       public static void Main()
       {
          N<int> n = new N<int>();
          X x = new X();
       }
    }
    
  • In einigen Fällen stellt .NET Native unterschiedliche Implementierungen von .NET Framework-Klassenbibliotheken bereit. Ein von einer Methode zurückgegebenes Objekt implementiert immer die Member des zurückgegebenen Typs. Da aber die Unterstützungsimplementierung unterschiedlich ist, können Sie es möglicherweise nicht in dieselben Typen wie auf anderen .NET Framework-Plattformen umwandeln. In einigen Fällen sind Sie zum Beispiel möglicherweise nicht in der Lage, das IEnumerable<T> -Schnittstellenobjekt, das von Methoden wie TypeInfo.DeclaredMembers oder TypeInfo.DeclaredProperties zurückgegeben wird, in T[]umzuwandeln.

  • Der WinInet-Cache ist in .NET für Windows 8.x-Apps standardmäßig nicht aktiviert, aber auf .NET Native. Dies verbessert die Leistung, hat aber Auswirkungen auf das Workingset. Es ist keine Entwickleraktion erforderlich.

Dynamische Programmierunterschiede

.NET Native verknüpft statisch in Code aus .NET Framework, um die Code-App lokal für maximale Leistung zu machen. Binäre Größen müssen jedoch klein bleiben, sodass nicht das gesamte .NET Framework einbezogen werden kann. Der .NET Native-Compiler löst diese Einschränkung mithilfe eines Abhängigkeitsminders auf, der Verweise auf nicht verwendete Code entfernt. .NET Native verwaltet oder generiert jedoch möglicherweise keine Typinformationen und Code, wenn diese Informationen zur Kompilierungszeit nicht statisch abgeleitet werden können, sondern zur Laufzeit dynamisch abgerufen werden.

.NET Native aktiviert Spiegelung und dynamische Programmierung. Nicht alle Typen können jedoch zur Reflexion markiert werden, da dadurch die generierte Codegröße zu groß wird (insbesondere, weil öffentliche APIs in .NET Framework unterstützt werden). Der .NET Native-Compiler trifft intelligente Entscheidungen darüber, welche Typen die Spiegelung unterstützen sollen, und behält die Metadaten bei und generiert Code nur für diese Typen.

Beispielsweise erfordert die Datenbindung, dass eine App Eigenschaftennamen Funktionen zuordnen kann. In .NET für Windows 8.x-Apps verwendet die Common Language Runtime automatisch Spiegelung, um diese Funktion für verwaltete Typen und öffentlich verfügbare systemeigene Typen bereitzustellen. In .NET Native enthält der Compiler automatisch Metadaten für Typen, an die Sie Daten binden.

Der .NET Native-Compiler kann auch häufig verwendete generische Typen wie List<T> und Dictionary<TKey,TValue>, die funktionieren, ohne dass Hinweise oder Direktiven erforderlich sind. Das dynamic -Schlüsselwort wird ebenfalls innerhalb bestimmter Grenzen unterstützt.

Hinweis

Sie sollten alle dynamischen Codepfade gründlich testen, wenn Sie Ihre App zu .NET Native portieren.

Die Standardkonfiguration für .NET Native reicht für die meisten Entwickler aus, aber einige Entwickler möchten ihre Konfigurationen möglicherweise mithilfe einer Laufzeitdirektivendatei (.rd.xml) optimieren. Darüber hinaus kann der .NET Native-Compiler in einigen Fällen nicht ermitteln, welche Metadaten zur Reflexion verfügbar sein müssen, und basiert auf Hinweisen, insbesondere in den folgenden Fällen:

  • Einige Konstrukte wie Type.MakeGenericType und MethodInfo.MakeGenericMethod können nicht statisch bestimmt werden.

  • Da der Compiler die Instanziierungen nicht ermitteln kann, muss ein generischer Typ, den Sie für die Reflektion verwenden möchten, durch Laufzeitdirektiven angegeben werden. Nicht nur, weil der gesamte Code enthalten sein muss, sondern auch, weil die Reflektion für generische Typen (z. B. wenn eine generische Methode für einen generischen Typ aufgerufen wird) einen unendlichen Zyklus bilden kann.

Hinweis

Laufzeitdirektiven werden in einer Laufzeitdirektivendatei (.rd.xml) definiert. Allgemeine Informationen zur Verwendung dieser Datei finden Sie unter Getting Started with .NET Native (Erste Schritte mit .NET Native). Informationen zu Laufzeitdirektiven finden Sie unter Runtime Directives (rd.xml) Configuration File Reference.

.NET Native enthält auch Profilerstellungstools, mit denen der Entwickler ermitteln kann, welche Typen außerhalb des Standardsatzes Spiegelung unterstützen sollen.

Es gibt eine Reihe weiterer individueller Spiegelungsunterschiede zwischen .NET für Windows 8.x-Apps und .NET Native.

In .NET Native:

  • Private Reflektion über Typen und Member in der .NET Framework-Klassenbibliothek wird nicht unterstützt. Sie können jedoch eigene private Typen und Member sowie Typen und Member in Bibliotheken von Drittanbietern für die Reflektion verwenden.

  • Die ParameterInfo.HasDefaultValue -Eigenschaft gibt ordnungsgemäß false für ein ParameterInfo -Objekt zurück, das einen Rückgabewert darstellt. In .NET für Windows 8.x-Apps wird sie zurückgegeben true. Dies wird nicht direkt unterstützt, und die Interpretation bleibt der Sprache überlassen.

  • Öffentliche Member in den RuntimeFieldHandle - und RuntimeMethodHandle -Strukturen werden nicht unterstützt. Diese Typen werden nur für LINQ, Ausdrucksbaumstrukturen und statische Arrayinitialisierungen unterstützt.

  • RuntimeReflectionExtensions.GetRuntimeProperties und RuntimeReflectionExtensions.GetRuntimeEvents enthalten ausgeblendete Member in Basisklassen und können daher ohne explizite Überschreibungen überschrieben werden. Dies gilt auch für andere RuntimeReflectionExtensions.GetRuntime* -Methoden.

  • Type.MakeArrayType und Type.MakeByRefType führen Sie keinen Fehler aus, wenn Sie versuchen, bestimmte Kombinationen zu erstellen (z. B. ein Array von byref Objekten).

  • Sie können mithilfe der Reflektion keine Member mit Zeigerparametern aufrufen.

  • Sie können mithilfe der Reflektion kein Zeigerfeld abrufen oder festlegen.

  • Wenn die Argumentanzahl falsch ist und der Typ eines der Argumente falsch ist, löst .NET Native anstelle ArgumentException einer .TargetParameterCountException

  • Binäre Serialisierung von Ausnahmen wird in der Regel nicht unterstützt. Daher können nicht serialisierbare Objekte zum Exception.Data -Wörterbuch hinzugefügt werden.

Nicht unterstützte Szenarios und APIs

In den folgenden Abschnitten werden nicht unterstützte Szenarios und APIs für allgemeine Entwicklung, Interop und Technologien wie HTTPClient und Windows Communication Foundation (WCF) aufgelistet:

Allgemeine Entwicklungsunterschiede

Werttypen

  • Wenn Sie die ValueType.Equals - und ValueType.GetHashCode -Methoden für einen Werttyp außer Kraft setzen, rufen Sie nicht die Implementierungen der Basisklasse auf. In .NET für Windows 8.x-Apps basieren diese Methoden auf Spiegelung. Zur Kompilierungszeit generiert .NET Native eine Implementierung, die nicht auf Laufzeitreflektion basiert. Dies bedeutet, dass sie, wenn Sie diese beiden Methoden nicht außer Kraft setzen, wie erwartet funktionieren, da .NET Native die Implementierung zur Kompilierungszeit generiert. Allerdings wird durch das Außerkraftsetzen dieser Methoden und das Aufrufen der Basisklassenimplementierung eine Ausnahme ausgelöst.

  • Werttypen, die größer als 1 MB sind, werden nicht unterstützt.

  • Werttypen können keinen parameterlosen Konstruktor in .NET Native aufweisen. (C# und Visual Basic verbieten parameterlose Konstruktoren für Werttypen. Diese können jedoch in IL erstellt werden.)

Arrays

  • Arrays mit einer unteren Grenze ungleich null werden nicht unterstützt. Diese Arrays werden in der Regel durch Aufrufen der Array.CreateInstance(Type, Int32[], Int32[]) -Überladung erstellt.

  • Die dynamische Erstellung von mehrdimensionalen Arrays wird nicht unterstützt. Solche Arrays werden in der Regel durch Aufruf einer Überladung für die Array.CreateInstance -Methode erstellt, die einen lengths -Parameter enthält, oder durch Aufrufen der Type.MakeArrayType(Int32) -Methode.

  • Mehrdimensionale Arrays mit vier oder mehr Dimensionen werden nicht unterstützt. Das heißt, der Array.Rank -Eigenschaftswert ist vier oder größer. Verwenden Sie stattdessen verzweigte Arrays (ein Array aus Arrays). array[x,y,z] ist zum Beispiel ungültig, array[x][y][z] aber nicht.

  • Varianz für mehrdimensionale Arrays wird nicht unterstützt und verursacht eine InvalidCastException -Ausnahme zur Laufzeit.

Generics

  • Unendliche generische Typerweiterung führt zu einem Compilerfehler. Dieser Code kann z. B. nicht kompiliert werden:

    class A<T> {}
    
    class B<T> : A<B<A<T>>>
    {}
    

Zeiger

  • Arrays aus Zeigern werden nicht unterstützt.

  • Sie können mithilfe der Reflektion kein Zeigerfeld abrufen oder festlegen.

Serialisierung

Die KnownTypeAttribute(String) -Attribut wird nicht unterstützt. Verwenden Sie stattdessen das KnownTypeAttribute(Type) -Attribut.

Ressourcen

Die Verwendung von lokalisierten Ressourcen mit der EventSource -Klasse wird nicht unterstützt. Die EventSourceAttribute.LocalizationResources -Eigenschaft definiert keine lokalisierten Ressourcen.

Delegaten

Delegate.BeginInvoke und Delegate.EndInvoke werden nicht unterstützt.

Verschiedene APIs

  • Die TypeInfo.GUID-Eigenschaft löst eine PlatformNotSupportedException Ausnahme aus, wenn ein GuidAttribute Attribut nicht auf den Typ angewendet wird. Die GUID wird in erster Linie für die COM-Unterstützung verwendet.

  • Die DateTime.Parse Methode analysiert ordnungsgemäß Zeichenfolgen, die kurze Datumswerte in .NET Native enthalten. Die Kompatibilität mit bestimmten Änderungen in der Datums- und Uhrzeitanalyse wird jedoch nicht beibehalten.

  • BigInteger.ToString("E") wird in .NET Native korrekt gerundet. In einigen Versionen der CLR wird die resultierende Zeichenfolge abgeschnitten und nicht gerundet.

HttpClient-Unterschiede

In .NET Native verwendet die HttpClientHandler Klasse intern WinINet (über die HttpBaseProtocolFilter Klasse) anstelle der WebRequest WebResponse Klassen, die in den standardmäßigen .NET für Windows 8.x-Apps verwendet werden. WinINet unterstützt nicht alle Konfigurationsoptionen, die die HttpClientHandler -Klasse unterstützt. Infolgedessen:

  • Einige der Funktionseigenschaften, die auf .NET Native zurückgegeben false werdenHttpClientHandler, während sie in den standardmäßigen .NET für Windows 8.x-Apps zurückgegeben werdentrue.

  • Einige der Konfigurationseigenschaftsaccessoren get geben immer einen festen Wert in .NET Native zurück, der sich von dem konfigurierbaren Standardwert in .NET für Windows 8.x-Apps unterscheidet.

In den folgenden Abschnitten werden einige zusätzliche Verhaltensunterschiede behandelt.

Proxy

Die HttpBaseProtocolFilter Klasse unterstützt nicht die Konfiguration oder Außerkraftsetzung des Proxys pro Anforderung. Dies bedeutet, dass alle Anforderungen auf .NET Native abhängig vom Wert der HttpClientHandler.UseProxy Eigenschaft den vom System konfigurierten Proxyserver oder keinen Proxyserver verwenden. In .NET für Windows 8.x-Apps wird der Proxyserver durch die HttpClientHandler.Proxy Eigenschaft definiert. Bei .NET Native löst das Festlegen des HttpClientHandler.Proxy Werts auf einen anderen Wert als null eine Ausnahme aus PlatformNotSupportedException . Die HttpClientHandler.SupportsProxy Eigenschaft gibt .NET Native zurück false , während sie in den standardmäßigen .NET Framework für Windows 8.x-Apps zurückgegeben wird true .

Automatische Umleitung

Die HttpBaseProtocolFilter Klasse lässt nicht zu, dass die maximale Anzahl von automatischen Umleitungen konfiguriert werden kann. Der Wert der HttpClientHandler.MaxAutomaticRedirections Eigenschaft ist standardmäßig 50 in den standardmäßigen .NET für Windows 8.x-Apps und kann geändert werden. Bei .NET Native ist der Wert dieser Eigenschaft 10, und der Versuch, sie zu ändern, löst eine PlatformNotSupportedException Ausnahme aus. Die HttpClientHandler.SupportsRedirectConfiguration Eigenschaft gibt .NET Native zurück false , während sie in .NET für Windows 8.x-Apps zurückgegeben wird true .

Automatische Dekomprimierung

Mit .NET für Windows 8.x-Apps können Sie die HttpClientHandler.AutomaticDecompression Eigenschaft auf Deflate, GZipsowohl als GZipauch Deflate auf .None .NET Native unterstützt Deflate nur zusammen mit GZip, oder None. Wenn Sie versuchen, die AutomaticDecompression -Eigenschaft im Hintergrund auf Deflate oder GZip festzulegen, wird sie auf Deflate und GZipfestgelegt.

Cookies

Cookieverarbeitung erfolgt gleichzeitig durch HttpClient und WinINet. Cookies aus dem CookieContainer werden mit Cookies im WinINet-Cookiecache kombiniert. Durch das Entfernen eines Cookies aus CookieContainer wird HttpClient am Senden des Cookies gehindert. Wenn der Cookie aber schon von WinINet erkannt wurde und Cookies nicht vom Benutzer gelöscht wurden, wird er durch WinINet gesendet. Es ist nicht möglich, einen Cookie programmgesteuert aus WinINet mithilfe der HttpClient-, HttpClientHandler- oder CookieContainer -API zu entfernen. Durch das Festlegen der HttpClientHandler.UseCookies -Eigenschaft auf false sendet HttpClient keine Cookies mehr; WinINet kann die Cookies immer noch in der Anforderung einschließen.

Anmeldeinformationen

In .NET für Windows 8.x-Apps funktionieren die und HttpClientHandler.Credentials die HttpClientHandler.UseDefaultCredentials Eigenschaften unabhängig voneinander. Darüber hinaus akzeptiert die Credentials -Eigenschaft jedes Objekt, das die ICredentials -Schnittstelle implementiert. Legen Sie in .NET Native die UseDefaultCredentials Eigenschaft so fest, dass true die Credentials Eigenschaft wird null. Außerdem kann die Credentials -Eigenschaft nur auf null, DefaultCredentialsoder ein Objekt vom Typ NetworkCredentialfestgelegt werden. Wenn ein beliebiges anderes ICredentials -Objekt, zum Beispiel das sehr beliebte CredentialCache-Objekt, der Credentials -Eigenschaft zugeweisen wird, wird eine PlatformNotSupportedExceptionausgelöst.

Andere nicht unterstützte oder nicht konfigurierbare Features

In .NET Native:

Interop-Unterschiede

Nicht mehr unterstützte APIs

Eine Reihe von selten verwendeten APIs für die Interoperabilität mit verwaltetem Code werden nicht mehr unterstützt. Bei Verwendung mit .NET Native können diese APIs eine NotImplementedException Oder PlatformNotSupportedException Ausnahme auslösen oder zu einem Compilerfehler führen. In .NET für Windows 8.x-Apps sind diese APIs als veraltet gekennzeichnet, obwohl beim Aufrufen eine Compilerwarnung anstelle eines Compilerfehlers generiert wird.

Veraltete APIs für VARIANT Marshaling umfassen:

UnmanagedType.Struct wird unterstützt, löst jedoch in einigen Szenarien eine Ausnahme aus, z. B. wenn sie mit IDispatch oder byref Varianten verwendet wird.

Veraltete APIs für die IDispatch-Unterstützung umfassen:

Veraltete APIs für klassische COM-Ereignisse umfassen:

Veraltete APIs in der System.Runtime.InteropServices.ICustomQueryInterface Schnittstelle, die in .NET Native nicht unterstützt werden, umfassen:

Weitere nicht unterstützte Interoperabilitätsfeatures sind:

Selten verwendete Marshalling-APIs:

Plattformaufruf und COM-Interop-Kompatibilität

Die meisten Plattform-Aufruf- und COM-Interoperabilitätsszenarien werden in .NET Native weiterhin unterstützt. Insbesondere werden die gesamte Interoperabilität mit WinRT-APIs (Windows-Runtime) und das gesamte Marshalling unterstützt, das für Windows-Runtime erforderlich ist. Dazu gehört die Marshallingunterstützung für:

.NET Native unterstützt jedoch folgendes nicht:

Das Verwenden von Reflektion zum Aufrufen einer Plattformaufrufmethode wird nicht unterstützt. Sie können diese Einschränkung umgehen, indem Sie den Methodenaufruf in eine andere Methode einschließen und den Wrapper stattdessen mithilfe von Reflektion aufrufen.

Andere Unterschiede von .NET-APIs für Windows 8.x-Apps

In diesem Abschnitt werden die verbleibenden APIs aufgeführt, die in .NET Native nicht unterstützt werden. Der größte Satz der nicht unterstützten APIs ist die Windows Communication Foundation (WCF)-APIs.

DataAnnotations (System.ComponentModel.DataAnnotations)

Die Typen in den System.ComponentModel.DataAnnotations Namespaces und System.ComponentModel.DataAnnotations.Schema in .NET Native werden nicht unterstützt. Dazu gehören die folgenden Typen, die in .NET für Windows 8.x-Apps vorhanden sind:

Visual Basic

Visual Basic wird derzeit in .NET Native nicht unterstützt. Die folgenden Typen in den Microsoft.VisualBasic Namespaces sind Microsoft.VisualBasic.CompilerServices in .NET Native nicht verfügbar:

Reflection Context (System.Reflection.Context-Namespace)

Die System.Reflection.Context.CustomReflectionContext Klasse wird in .NET Native nicht unterstützt.

RTC (System.Net.Http.Rtc)

Die System.Net.Http.RtcRequestFactory Klasse wird in .NET Native nicht unterstützt.

Windows Communication Foundation (WCF) (System.ServiceModel.*)

Die Typen in den System.ServiceModel.* -Namespaces werden in .NET Native nicht unterstützt. Dazu gehören die folgenden Typen:

Unterschiede in den Serialisierungsprogrammen

Die folgenden Unterschiede betreffen die Serialisierung und Deserialisierung mit den Klassen DataContractSerializer, DataContractJsonSerializerund XmlSerializer :

Visual Studio-Unterschiede

Ausnahmen und Debuggen

Wenn Sie Apps ausführen, die mithilfe von .NET Native im Debugger kompiliert werden, werden Ausnahmen mit der ersten Chance für die folgenden Ausnahmetypen aktiviert:

Erstellen von Anwendungen

Verwenden Sie die x86-Buildtools, die standardmäßig von Visual Studio verwendet werden. Sie sollten nicht die AMD64-MSBuild-Tools unter "C:\Program Files (x86)\MSBuild\12.0\bin\amd64" verwenden. Diese können Buildprobleme verursachen.

Profiler

  • Der Visual Studio-CPU-Profiler und der XAML-Arbeitsspeicherprofiler zeigen "Nur mein Code" nicht ordnungsgemäß an.

  • Der XAML-Arbeitsspeicherprofiler zeigt verwaltete Heapdaten nicht ordnungsgemäß an.

  • Der CPU-Profiler identifiziert Module nicht ordnungsgemäß und zeigt Funktionsnamen mit Präfix an.

Komponententest-Bibliotheksprojekte

Das Aktivieren von .NET Native in einer Komponententestbibliothek für ein Windows 8.x-App-Projekt wird nicht unterstützt und bewirkt, dass das Projekt nicht erstellt wird.

Siehe auch