Contoh: Pemecahan Masalah Pemrograman Dinamis
Catatan
Topik ini mengacu pada Pratinjau Pengembang Asli .NET, yang merupakan perangkat lunak pra-rilis. Anda dapat mengunduh pratinjau dari situs web Microsoft Connect (memerlukan pendaftaran).
Tidak semua kegagalan pencarian metadata dalam aplikasi yang dikembangkan menggunakan rantai alat .NET Native menghasilkan pengecualian. Beberapa dapat bermanifestasi dengan cara yang tidak dapat diprediksi dalam aplikasi. Contoh berikut menunjukkan pelanggaran akses yang disebabkan oleh mereferensikan objek null:
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]
Mari kita coba memecahkan masalah pengecualian ini dengan menggunakan pendekatan tiga langkah yang diuraikan di bagian "Selesaikan metadata yang hilang" secara manual di Memulai.
Apa yang dilakukan aplikasi ini?
Hal pertama yang perlu diperhatikan adalah async
mesin kata kunci di dasar tumpukan. Menentukan apa yang sebenarnya dilakukan aplikasi dalam metode async
bisa bermasalah, karena tumpukan telah kehilangan konteks panggilan asal dan telah menjalankan async
kode pada utas yang berbeda. Namun, kita dapat menyimpulkan bahwa aplikasi mencoba memuat halaman pertamanya. Dalam implementasi untuk NavigationArgs.Setup
, kode berikut menyebabkan pelanggaran akses:
AppViewModel.Current.LayoutVM.PageMap
Dalam hal ini, LayoutVM
properti pada AppViewModel.Current
null. Beberapa tidak adanya metadata menyebabkan perbedaan perilaku yang halus dan mengakibatkan properti tidak diinisialisasi alih-alih diatur, seperti yang diharapkan aplikasi. Mengatur titik henti dalam kode di mana LayoutVM
seharusnya diinisialisasi dapat melemparkan cahaya pada situasi. Namun, perhatikan bahwa LayoutVM
jenisnya adalah App.Core.ViewModels.Layout.LayoutApplicationVM
. Satu-satunya arahan metadata yang ada sejauh ini dalam file rd.xml adalah:
<Namespace Name="App.ViewModels" Browse="Required Public" Dynamic="Required Public" />
Kemungkinan kandidat untuk kegagalan adalah metadata yang App.Core.ViewModels.Layout.LayoutApplicationVM
hilang karena berada di namespace yang berbeda.
Dalam hal ini, menambahkan arahan runtime untuk App.Core.ViewModels
menyelesaikan masalah. Akar penyebabnya adalah panggilan API ke Type.GetType(String) metode yang mengembalikan null, dan aplikasi secara diam-diam mengabaikan masalah sampai terjadi crash.
Dalam pemrograman dinamis, praktik yang baik saat menggunakan API refleksi di bawah .NET Native adalah menggunakan Type.GetType kelebihan beban yang melemparkan pengecualian pada kegagalan.
Apakah ini kasus terisolasi?
Masalah lain mungkin juga muncul saat menggunakan App.Core.ViewModels
. Anda harus memutuskan apakah ada baiknya mengidentifikasi dan memperbaiki setiap pengecualian metadata yang hilang, atau menghemat waktu dan menambahkan arahan untuk kelas jenis yang lebih besar. Di sini, menambahkan dynamic
metadata App.Core.ViewModels
mungkin merupakan pendekatan terbaik jika peningkatan ukuran yang dihasilkan dari biner output bukan masalah.
Bisakah kode ditulis ulang?
Jika aplikasi telah digunakan typeof(LayoutApplicationVM)
alih-alih Type.GetType("LayoutApplicationVM")
, rantai alat dapat mempertahankan browse
metadata. Namun, itu masih tidak akan membuat invoke
metadata, yang akan menyebabkan pengecualian MissingMetadataException saat membuat instans jenis. Untuk mencegah pengecualian, Anda masih harus menambahkan arahan runtime untuk namespace layanan atau jenis yang menentukan dynamic
kebijakan. Untuk informasi tentang arahan runtime, lihat Referensi File Konfigurasi Runtime Directives (rd.xml).