Bagikan melalui


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 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 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).

Lihat juga