Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Saat menerbitkan aplikasi Anda sebagai Native AOT, proses build menghasilkan semua kode asli dan struktur data yang diperlukan untuk mendukung aplikasi pada runtime. Ini berbeda dari penyebaran non-asli, yang menjalankan aplikasi dari format yang menjelaskan aplikasi dalam istilah abstrak (program untuk komputer virtual) dan membuat representasi asli sesuai permintaan pada runtime.
Representasi abstrak bagian program tidak memiliki pemetaan satu-ke-satu ke representasi asli. Misalnya, deskripsi abstrak dari metode generik List<T>.Add memetakan ke badan metode bawaan yang berpotensi tak terbatas dan perlu disesuaikan untuk T tertentu (misalnya, List<int>.Add dan List<double>.Add).
Karena hubungan kode abstrak ke kode asli bukan satu-ke-satu, proses build perlu membuat daftar lengkap badan kode asli dan struktur data pada waktu build. Mungkin sulit untuk membuat daftar ini pada waktu build untuk beberapa API .NET. Jika API digunakan dengan cara yang tidak diantisipasi pada waktu build, pengecualian akan dilemparkan pada runtime.
Untuk mencegah perubahan perilaku saat menyebarkan sebagai Native AOT, .NET SDK menyediakan analisis statis kompatibilitas AOT melalui "peringatan AOT." Peringatan AOT dihasilkan ketika build menemukan kode yang mungkin tidak kompatibel dengan AOT. Kode yang tidak kompatibel dengan AOT dapat menghasilkan perubahan perilaku atau bahkan crash dalam aplikasi setelah dibuat sebagai AOT Asli. Idealnya, semua aplikasi yang menggunakan AOT Native seharusnya tidak memiliki peringatan AOT. Jika ada peringatan terkait AOT, pastikan tidak ada perubahan perilaku dengan menguji aplikasi Anda secara menyeluruh setelah membangunnya sebagai Native AOT.
Contoh peringatan AOT
Untuk sebagian besar kode C#, sangat mudah untuk menentukan kode asli apa yang perlu dihasilkan. Pengkompilasi asli dapat memandu badan metode dan menemukan kode asli dan struktur data apa yang diakses. Sayangnya, beberapa fitur, seperti refleksi, menghadirkan masalah yang signifikan. Pertimbangkan kode berikut:
Type t = typeof(int);
while (true)
{
t = typeof(GenericType<>).MakeGenericType(t);
Console.WriteLine(Activator.CreateInstance(t));
}
struct GenericType<T> { }
Meskipun program di atas kurang berguna, ini mewakili kasus ekstrem yang membutuhkan pembuatan jumlah tak terbatas jenis generik saat membangun aplikasi sebagai Native AOT. Tanpa Native AOT, program akan berjalan sampai kehabisan memori. Dengan Native AOT, kita tidak akan dapat bahkan membangunnya jika kita menghasilkan semua jenis yang diperlukan (jumlah tak terbatas dari mereka).
Dalam hal ini, build AOT Asli mengeluarkan peringatan berikut di MakeGenericType baris:
AOT analysis warning IL3050: Program.<Main>$(String[]): Using member 'System.Type.MakeGenericType(Type[])' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The native code for this instantiation might not be available at runtime.
Saat runtime, aplikasi memang akan melemparkan pengecualian dari panggilan MakeGenericType.
Bereaksi terhadap peringatan AOT
Peringatan AOT dimaksudkan untuk membawa prediktabilitas ke build AOT bawaan. Sebagian besar peringatan AOT adalah tentang kemungkinan pengecualian runtime dalam situasi ketika kode asli tidak dihasilkan untuk mendukung skenario. Kategori terluas adalah RequiresDynamicCodeAttribute.
MemerlukanKodeDinamis
RequiresDynamicCodeAttribute sederhana dan luas: ini adalah atribut yang berarti anggota telah dianotasikan sebagai tidak kompatibel dengan AOT. Anotasi ini berarti bahwa anggota mungkin menggunakan refleksi atau mekanisme lain untuk membuat kode asli baru saat runtime. Atribut ini digunakan ketika kode pada dasarnya tidak kompatibel dengan AOT, atau dependensi asli terlalu kompleks untuk diprediksi secara statis pada waktu build. Ini sering kali berlaku untuk metode yang menggunakan Type.MakeGenericType API, emisi refleksi, atau teknologi pembuatan kode runtime lainnya. Kode berikut menunjukkan contoh.
[RequiresDynamicCode("Use 'MethodFriendlyToAot' instead")]
void MethodWithReflectionEmit() { ... }
void TestMethod()
{
// IL3050: Using method 'MethodWithReflectionEmit' which has 'RequiresDynamicCodeAttribute'
// can break functionality when AOT compiling. Use 'MethodFriendlyToAot' instead.
MethodWithReflectionEmit();
}
Tidak ada banyak solusi untuk RequiresDynamicCode. Perbaikan terbaik adalah menghindari memanggil metode sama sekali saat membangun sebagai AOT Asli dan menggunakan sesuatu yang kompatibel dengan AOT. Jika Anda menulis pustaka dan tidak ada dalam kontrol Anda apakah akan memanggil metode atau tidak, Anda juga dapat menambahkan RequiresDynamicCode ke metode Anda sendiri. Ini akan menganotasi metode Anda sebagai tidak kompatibel dengan AOT. Menambahkan RequiresDynamicCode akan menghilangkan semua peringatan AOT dalam metode yang dianotasi tetapi akan menghasilkan peringatan setiap kali orang lain memanggilnya. Untuk alasan ini, sebagian besar berguna bagi pengembang pustaka untuk mengeskalasi peringatan ke API publik.
Jika Anda entah bagaimana dapat menentukan bahwa panggilan aman, dan semua kode asli akan tersedia saat runtime, Anda juga dapat menekan peringatan menggunakan UnconditionalSuppressMessageAttribute. Contohnya:
[RequiresDynamicCode("Use 'MethodFriendlyToAot' instead")]
void MethodWithReflectionEmit() { ... }
[UnconditionalSuppressMessage("Aot", "IL3050:RequiresDynamicCode",
Justification = "The unfriendly method is not reachable with AOT")]
void TestMethod()
{
If (RuntimeFeature.IsDynamicCodeSupported)
MethodWithReflectionEmit(); // warning suppressed
}
UnconditionalSuppressMessage seperti SuppressMessage tetapi dapat dilihat oleh publish dan alat pasca-build lainnya.
SuppressMessage dan #pragma direktif hanya ada di sumber, sehingga tidak dapat digunakan untuk mengatasi peringatan dalam proses build.
Perhatian
Berhati-hatilah saat mengabaikan peringatan AOT. Pemanggilan mungkin kompatibel dengan AOT sekarang, tetapi ketika Anda memperbarui kode Anda, itu mungkin berubah, dan Anda mungkin lupa meninjau semua penyembunyian.