Bagikan melalui


Memigrasikan Aplikasi Windows 8.x Anda ke .NET Native

.NET Native menyediakan kompilasi statis aplikasi di Microsoft Store atau di komputer pengembang. Ini berbeda dari kompilasi dinamis yang dilakukan untuk aplikasi Windows 8.x (juga sebelumnya disebut aplikasi Microsoft Store) oleh kompilator just-in-time (JIT) atau Native Image Generator (Ngen.exe) pada perangkat. Terlepas dari perbedaannya, .NET Native mencoba mempertahankan kompatibilitas dengan aplikasi .NET untuk Windows 8.x. Sebagian besar, hal-hal yang berfungsi pada aplikasi .NET untuk Windows 8.x juga berfungsi dengan .NET Native. Namun, dalam beberapa kasus, Anda mungkin mengalami perubahan perilaku. Dokumen ini membahas perbedaan antara aplikasi .NET standar untuk Windows 8.x dan .NET Native di area berikut:

Perbedaan runtime umum

  • Pengecualian, seperti TypeLoadException, yang dilemparkan oleh pengkompilasi JIT saat aplikasi berjalan pada runtime bahasa umum (CLR) umumnya mengakibatkan kesalahan waktu kompilasi saat diproses oleh .NET Native.

  • Jangan panggil GC.WaitForPendingFinalizers metode dari utas UI aplikasi. Ini dapat mengakibatkan kebuntuan pada .NET Native.

  • Jangan mengandalkan urutan pemanggilan konstruktor kelas statis. Di .NET Native, urutan pemanggilan berbeda dari urutan pada runtime standar. (Bahkan dengan runtime standar, Anda tidak boleh mengandalkan urutan eksekusi konstruktor kelas statis.)

  • Perulangan tak terbatas tanpa melakukan panggilan (misalnya, while(true);) pada utas apa pun dapat membuat aplikasi dihentikan. Demikian pula, penantian besar atau tak terbatas dapat membuat aplikasi berhenti.

  • Siklus inisialisasi generik tertentu tidak melemparkan pengecualian di .NET Native. Misalnya, kode berikut melemparkan TypeLoadException pengecualian pada CLR standar. Di .NET Native, tidak.

    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();
       }
    }
    
  • Dalam beberapa kasus, .NET Native menyediakan implementasi pustaka kelas .NET Framework yang berbeda. Objek yang dikembalikan dari metode akan selalu mengimplementasikan anggota jenis yang dikembalikan. Namun, karena implementasi dukungannya berbeda, Anda mungkin tidak dapat melemparkannya ke serangkaian jenis yang sama seperti yang Anda bisa pada platform .NET Framework lainnya. Misalnya, dalam beberapa kasus, Anda mungkin tidak dapat mentransmisikan objek antarmuka yang IEnumerable<T> dikembalikan oleh metode seperti TypeInfo.DeclaredMembers atau TypeInfo.DeclaredProperties ke T[].

  • Cache WinInet tidak diaktifkan secara default pada aplikasi .NET untuk Windows 8.x, tetapi ada di .NET Native. Ini meningkatkan performa tetapi memiliki implikasi set kerja. Tidak ada tindakan pengembang yang diperlukan.

Perbedaan pemrograman dinamis

.NET Native secara statis menautkan dalam kode dari .NET Framework untuk membuat aplikasi kode lokal untuk performa maksimum. Namun, ukuran biner harus tetap kecil, sehingga seluruh .NET Framework tidak dapat dibawa masuk. Pengkompilasi .NET Native menyelesaikan batasan ini dengan menggunakan peredam dependensi yang menghapus referensi ke kode yang tidak digunakan. Namun, .NET Native mungkin tidak mempertahankan atau menghasilkan beberapa informasi jenis dan kode ketika informasi tersebut tidak dapat disimpulkan secara statis pada waktu kompilasi, tetapi sebaliknya diambil secara dinamis saat runtime.

.NET Native memang memungkinkan refleksi dan pemrograman dinamis. Namun, tidak semua jenis dapat ditandai untuk refleksi, karena ini akan membuat ukuran kode yang dihasilkan terlalu besar (terutama karena mencerminkan API publik di .NET Framework didukung). Pengkompilasi .NET Native membuat pilihan cerdas tentang jenis mana yang harus mendukung refleksi, dan menyimpan metadata dan menghasilkan kode hanya untuk jenis tersebut.

Misalnya, pengikatan data mengharuskan aplikasi untuk dapat memetakan nama properti ke fungsi. Di aplikasi .NET untuk Windows 8.x, runtime bahasa umum secara otomatis menggunakan refleksi untuk menyediakan kemampuan ini untuk jenis terkelola dan jenis asli yang tersedia untuk umum. Di .NET Native, pengkompilasi secara otomatis menyertakan metadata untuk jenis yang Anda ikat datanya.

Pengkompilasi .NET Native juga dapat menangani jenis generik yang umum digunakan seperti List<T> dan Dictionary<TKey,TValue>, yang berfungsi tanpa memerlukan petunjuk atau arahan apa pun. Kata kunci dinamis juga didukung dalam batas tertentu.

Catatan

Anda harus menguji semua jalur kode dinamis secara menyeluruh saat memindahkan aplikasi Anda ke .NET Native.

Konfigurasi default untuk .NET Native cukup untuk sebagian besar pengembang, tetapi beberapa pengembang mungkin ingin menyempurnakan konfigurasi mereka dengan menggunakan file arahan runtime (.rd.xml). Selain itu, dalam beberapa kasus, pengkompilasi .NET Native tidak dapat menentukan metadata mana yang harus tersedia untuk refleksi dan bergantung pada petunjuk, terutama dalam kasus berikut:

  • Beberapa konstruksi seperti Type.MakeGenericType dan MethodInfo.MakeGenericMethod tidak dapat ditentukan secara statis.

  • Karena pengkompilasi tidak dapat menentukan instansiasi, jenis generik yang ingin Anda refleksikan harus ditentukan oleh arahan runtime. Ini bukan hanya karena semua kode harus disertakan, tetapi karena refleksi pada jenis generik dapat membentuk siklus tak terbatas (misalnya, ketika metode generik dipanggil pada jenis generik).

Catatan

Arahan runtime ditentukan dalam file arahan runtime (.rd.xml). Untuk informasi umum tentang menggunakan file ini, lihat Memulai. Untuk informasi tentang arahan runtime, lihat Referensi File Konfigurasi Runtime Directives (rd.xml).

.NET Native juga menyertakan alat pembuatan profil yang membantu pengembang menentukan jenis mana di luar set default yang harus mendukung refleksi.

Ada sejumlah perbedaan terkait refleksi individu lainnya dalam perilaku antara aplikasi .NET untuk Windows 8.x dan .NET Native.

Di .NET Native:

  • Refleksi privat atas jenis dan anggota di pustaka kelas .NET Framework tidak didukung. Namun, Anda dapat mencerminkan jenis dan anggota privat Anda sendiri, serta jenis dan anggota di pustaka pihak ketiga.

  • Properti ParameterInfo.HasDefaultValue mengembalikan false dengan benar untuk ParameterInfo objek yang mewakili nilai pengembalian. Di aplikasi .NET untuk Windows 8.x, aplikasi mengembalikan true. Bahasa perantara (IL) tidak mendukung ini secara langsung, dan interpretasi diserahkan ke bahasa tersebut.

  • Anggota publik pada RuntimeFieldHandle struktur dan RuntimeMethodHandle tidak didukung. Jenis ini hanya didukung untuk LINQ, pohon ekspresi, dan inisialisasi array statis.

  • RuntimeReflectionExtensions.GetRuntimeProperties dan RuntimeReflectionExtensions.GetRuntimeEvents sertakan anggota tersembunyi dalam kelas dasar dan dengan demikian dapat ditimpa tanpa penimpaan eksplisit. Ini juga berlaku untuk metode RuntimeReflectionExtensions.GetRuntime* lainnya.

  • Type.MakeArrayType dan Type.MakeByRefType jangan gagal ketika Anda mencoba membuat kombinasi tertentu (misalnya, array byref objek).

  • Anda tidak dapat menggunakan pantulan untuk memanggil anggota yang memiliki parameter penunjuk.

  • Anda tidak dapat menggunakan pantulan untuk mendapatkan atau mengatur bidang penunjuk.

  • Ketika jumlah argumen salah dan jenis salah satu argumen salah, .NET Native melemparkan ArgumentException alih-alih TargetParameterCountException.

  • Serialisasi biner pengecualian umumnya tidak didukung. Akibatnya, objek yang tidak dapat diserialisasi dapat ditambahkan ke Exception.Data kamus.

Skenario dan API yang tidak didukung

Bagian berikut mencantumkan skenario dan API yang tidak didukung untuk pengembangan umum, interop, dan teknologi seperti HTTPClient dan Windows Communication Foundation (WCF):

Perbedaan pengembangan umum

Jenis nilai

  • Jika Anda mengambil ValueType.Equals alih metode dan ValueType.GetHashCode untuk jenis nilai, jangan panggil implementasi kelas dasar. Di aplikasi .NET untuk Windows 8.x, metode ini mengandalkan pantulan. Pada waktu kompilasi, .NET Native menghasilkan implementasi yang tidak bergantung pada refleksi runtime. Ini berarti bahwa jika Anda tidak mengambil alih kedua metode ini, metode tersebut akan berfungsi seperti yang diharapkan, karena .NET Native menghasilkan implementasi pada waktu kompilasi. Namun, mengesampingkan metode ini tetapi memanggil implementasi kelas dasar menghasilkan pengecualian.

  • Jenis nilai yang lebih besar dari 1 megabyte tidak didukung.

  • Jenis nilai tidak dapat memiliki konstruktor tanpa parameter di .NET Native. (C# dan Visual Basic melarang konstruktor tanpa parameter pada jenis nilai. Namun, ini dapat dibuat di IL.)

Array

  • Array dengan batas yang lebih rendah selain nol tidak didukung. Biasanya, array ini dibuat dengan memanggil Array.CreateInstance(Type, Int32[], Int32[]) kelebihan beban.

  • Pembuatan dinamis array multidansa tidak didukung. Array tersebut biasanya dibuat dengan memanggil kelebihan beban Array.CreateInstance metode yang mencakup lengths parameter, atau dengan memanggil Type.MakeArrayType(Int32) metode .

  • Array multidireksional yang memiliki empat dimensi atau lebih tidak didukung; artinya, nilai properti mereka Array.Rank adalah empat atau lebih besar. Gunakan array berjalur (array array) sebagai gantinya. Misalnya, array[x,y,z] tidak valid, tetapi array[x][y][z] tidak.

  • Varians untuk array multidimensi tidak didukung dan menyebabkan InvalidCastException pengecualian pada waktu proses.

Generik

  • Ekspansi jenis generik tak terbatas menghasilkan kesalahan kompilator. Misalnya, kode ini gagal dikompilasi:

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

Pointer

  • Array pointer tidak didukung.

  • Anda tidak dapat menggunakan pantulan untuk mendapatkan atau mengatur bidang penunjuk.

Serialisasi

Atribut KnownTypeAttribute(String) tidak didukung. Gunakan atribut sebagai gantinya KnownTypeAttribute(Type) .

Sumber

Penggunaan sumber daya yang dilokalkan dengan EventSource kelas tidak didukung. Properti EventSourceAttribute.LocalizationResources tidak menentukan sumber daya yang dilokalkan.

Delegasi

Delegate.BeginInvoke dan Delegate.EndInvoke tidak didukung.

API Lain-Lain

  • Properti TypeInfo.GUID melempar PlatformNotSupportedException pengecualian jika GuidAttribute atribut tidak diterapkan ke jenis . GUID digunakan terutama untuk dukungan COM.

  • Metode mengurai DateTime.Parse string dengan benar yang berisi tanggal pendek di .NET Native. Namun, ini tidak mempertahankan kompatibilitas dengan perubahan tertentu dalam penguraian tanggal dan waktu.

  • BigInteger.ToString("E") dibulatkan dengan benar di .NET Native. Dalam beberapa versi CLR, string hasil dipotong alih-alih dibulatkan.

Perbedaan HttpClient

Di .NET Native, HttpClientHandler kelas secara internal menggunakan WinINet (melalui HttpBaseProtocolFilter kelas) alih-alih WebRequest kelas dan WebResponse yang digunakan dalam aplikasi .NET standar untuk Windows 8.x. WinINet tidak mendukung semua opsi konfigurasi yang didukung HttpClientHandler kelas. Akibatnya:

  • Beberapa properti kemampuan saat HttpClientHandler kembali false pada .NET Native, sedangkan properti tersebut kembali true di aplikasi .NET standar untuk Windows 8.x.

  • Beberapa pengakses properti get konfigurasi selalu mengembalikan nilai tetap pada .NET Native yang berbeda dari nilai default yang dapat dikonfigurasi di aplikasi .NET untuk Windows 8.x.

Beberapa perbedaan perilaku tambahan tercakup dalam sub-bagian berikut.

Proksi

Kelas HttpBaseProtocolFilter tidak mendukung konfigurasi atau penimpaan proksi berdasarkan per permintaan. Ini berarti bahwa semua permintaan pada .NET Native menggunakan server proksi yang dikonfigurasi sistem atau tanpa server proksi, tergantung pada nilai HttpClientHandler.UseProxy properti . Di aplikasi .NET untuk Windows 8.x, server proksi ditentukan oleh HttpClientHandler.Proxy properti . Pada .NET Native, atur HttpClientHandler.Proxy ke nilai selain null melempar PlatformNotSupportedException pengecualian. Properti HttpClientHandler.SupportsProxy mengembalikan false pada .NET Native, sedangkan properti kembali true di aplikasi .NET Framework standar untuk Windows 8.x.

Pengalihan otomatis

Kelas HttpBaseProtocolFilter tidak mengizinkan jumlah maksimum pengalihan otomatis dikonfigurasi. Nilai HttpClientHandler.MaxAutomaticRedirections properti adalah 50 secara default di aplikasi .NET standar untuk Windows 8.x dan dapat dimodifikasi. Pada .NET Native, nilai properti ini adalah 10, dan mencoba memodifikasinya melemparkan PlatformNotSupportedException pengecualian. Properti HttpClientHandler.SupportsRedirectConfiguration mengembalikan false pada .NET Native, sedangkan properti mengembalikan true aplikasi .NET untuk Windows 8.x.

Dekompresi otomatis

Aplikasi .NET untuk Windows 8.x memungkinkan Anda mengatur HttpClientHandler.AutomaticDecompression properti ke Deflate, GZip, baik Deflate dan GZip, atau None. .NET Native hanya mendukung Deflate bersama dengan GZip, atau None. Mencoba mengatur AutomaticDecompression properti ke baik Deflate atau GZip sendiri secara diam-diam mengaturnya ke dan Deflate GZip.

Cookie

Penanganan cookie dilakukan secara bersamaan oleh HttpClient dan WinINet. Cookie dari dikombinasikan CookieContainer dengan cookie di cache cookie WinINet. Menghapus cookie mencegah CookieContainer HttpClient pengiriman cookie, tetapi jika cookie sudah dilihat oleh WinINet, dan cookie tidak dihapus oleh pengguna, WinINet mengirimkannya. Tidak dimungkinkan untuk menghapus cookie secara terprogram dari WinINet dengan menggunakan HttpClient, , HttpClientHandleratau CookieContainer API. HttpClientHandler.UseCookies Mengatur properti menjadi false penyebab hanya HttpClient berhenti mengirim cookie; WinINet mungkin masih menyertakan cookie dalam permintaan.

Informasi Masuk

Di aplikasi .NET untuk Windows 8.x, HttpClientHandler.UseDefaultCredentials properti dan HttpClientHandler.Credentials bekerja secara independen. Selain itu, Credentials properti menerima objek apa pun yang mengimplementasikan ICredentials antarmuka. Di .NET Native, atur UseDefaultCredentials properti untuk true menyebabkan Credentials properti menjadi null. Selain itu, Credentials properti hanya dapat diatur ke null, DefaultCredentials, atau objek jenis NetworkCredential. Menetapkan objek lainICredentials, yang paling populer adalah CredentialCache, ke Credentials properti melempar .PlatformNotSupportedException

Fitur lain yang tidak didukung atau tidak dapat dikonfigurasi

Di .NET Native:

Perbedaan interop

API yang tidak digunakan lagi

Sejumlah API yang jarang digunakan untuk interoperabilitas dengan kode terkelola telah ditolak. Saat digunakan dengan .NET Native, API ini dapat melemparkan NotImplementedException pengecualian atau PlatformNotSupportedException , atau mengakibatkan kesalahan kompilator. Di aplikasi .NET untuk Windows 8.x, API ini ditandai sebagai usang, meskipun memanggilnya menghasilkan peringatan kompilator daripada kesalahan kompilator.

API yang tidak digunakan lagi untuk VARIANT marshaling meliputi:

UnmanagedType.Struct didukung, tetapi melemparkan pengecualian dalam beberapa skenario, seperti ketika digunakan dengan IDispatch atau byref varian.

API yang tidak digunakan lagi untuk dukungan IDispatch meliputi:

API yang tidak digunakan lagi untuk peristiwa COM klasik meliputi:

API yang tidak digunakan lagi dalam System.Runtime.InteropServices.ICustomQueryInterface antarmuka, yang tidak didukung di .NET Native, meliputi:

Fitur interop lain yang tidak didukung meliputi:

API marshaling yang jarang digunakan:

Kompatibilitas interop platform dan com

Sebagian besar skenario pemanggilan platform dan interop COM masih didukung di .NET Native. Secara khusus, semua interoperabilitas dengan WINDOWS Runtime (WinRT) API dan semua marshaling yang diperlukan untuk Windows Runtime didukung. Ini termasuk dukungan marshaling untuk:

Namun, .NET Native tidak mendukung hal berikut:

Menggunakan refleksi untuk memanggil metode pemanggilan platform tidak didukung. Anda dapat mengatasi batasan ini dengan membungkus panggilan metode dalam metode lain dan menggunakan pantulan untuk memanggil pembungkus sebagai gantinya.

Perbedaan lain dari .NET API untuk aplikasi Windows 8.x

Bagian ini mencantumkan API yang tersisa yang tidak didukung di .NET Native. Sekumpulan API terbesar yang tidak didukung adalah API Windows Communication Foundation (WCF).

DataAnnotations (System.ComponentModel.DataAnnotations)

Jenis di System.ComponentModel.DataAnnotations namespace layanan dan System.ComponentModel.DataAnnotations.Schema tidak didukung di .NET Native. Ini termasuk jenis berikut yang ada di aplikasi .NET untuk Windows 8.x:

Visual Basic

Visual Basic saat ini tidak didukung di .NET Native. Jenis berikut di Microsoft.VisualBasic namespace layanan dan Microsoft.VisualBasic.CompilerServices tidak tersedia di .NET Native:

Konteks Pantulan (namespace layanan System.Reflection.Context)

Kelas System.Reflection.Context.CustomReflectionContext tidak didukung di .NET Native.

RTC (System.Net.Http.Rtc)

Kelas System.Net.Http.RtcRequestFactory tidak didukung di .NET Native.

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

Jenis di namespace System.ServiceModel.* tidak didukung di .NET Native. Ini termasuk jenis berikut:

Perbedaan dalam serializer

Perbedaan berikut menyangkut serialisasi dan deserialisasi dengan DataContractSerializerkelas , , DataContractJsonSerializerdan XmlSerializer :

Perbedaan Visual Studio

Pengecualian dan penelusuran kesalahan

Saat Anda menjalankan aplikasi yang dikompilasi dengan menggunakan .NET Native di debugger, pengecualian kesempatan pertama diaktifkan untuk jenis pengecualian berikut:

Membangun aplikasi

Gunakan alat build x86 yang digunakan secara default oleh Visual Studio. Kami tidak merekomendasikan penggunaan alat AMD64 MSBuild, yang ditemukan di C:\Program Files (x86)\MSBuild\12.0\bin\amd64; ini dapat membuat masalah build.

Profiler

  • Profiler CPU Visual Studio dan Profiler Memori XAML tidak menampilkan Just-My-Code dengan benar.

  • Profiler Memori XAML tidak menampilkan data timbunan terkelola secara akurat.

  • Profiler CPU tidak mengidentifikasi modul dengan benar, dan menampilkan nama fungsi awalan.

Proyek Pustaka Pengujian Unit

Mengaktifkan .NET Native pada Pustaka Pengujian Unit untuk proyek aplikasi Windows 8.x tidak didukung dan menyebabkan proyek gagal dibangun.

Lihat juga