Bagikan melalui


Contoh: Pemecahan Masalah Pemrograman Dinamis

Nota

Topik ini mengacu pada .NET Native Developer Preview, 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?

Hal pertama yang perlu diperhatikan adalah mesin kata sandi async di dasar dari tumpukan. Menentukan apa yang sebenarnya dilakukan aplikasi dalam metode async bisa bermasalah, karena stack kehilangan konteks dari pemanggilan asal dan menjalankan kode async pada utas lain. 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, properti LayoutVM pada AppViewModel.Current adalah null. Ketiadaan beberapa metadata menyebabkan perbedaan perilaku yang tidak terlihat dan mengakibatkan properti menjadi tidak diinisialisasi alih-alih diatur seperti yang diharapkan oleh aplikasi. Mengatur titik henti dalam kode di posisi LayoutVM seharusnya diinisialisasi mungkin memberikan kejelasan pada situasi. Namun, perhatikan bahwa LayoutVMjenisnya 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 penyebab dari kegagalan ini adalah App.Core.ViewModels.Layout.LayoutApplicationVM kehilangan metadata karena berada dalam ruang nama 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 metode overload Type.GetType yang melempar pengecualian jika terjadi 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 untuk App.Core.ViewModels mungkin merupakan pendekatan terbaik jika peningkatan ukuran yang dihasilkan dari output biner bukanlah masalah.

Bisakah kode ditulis ulang?

Jika aplikasi menggunakan typeof(LayoutApplicationVM) alih-alih Type.GetType("LayoutApplicationVM"), rantai alat dapat mempertahankan metadata browse. Namun, itu masih belum akan membuat metadata invoke, yang akan menimbulkan terjadinya pengecualian MissingMetadataException saat menginisialisasi tipe. Untuk mencegah pengecualian, Anda masih harus menambahkan arahan runtime untuk namespace atau tipe yang menentukan kebijakan dynamic. Untuk informasi tentang arahan waktu proses, lihat Referensi File Konfigurasi Arahan Waktu Proses (rd.xml).

Lihat juga