Sdílet prostřednictvím


Příklad: Řešení potíží s dynamickým programováním

Poznámka:

Toto téma se týká verze .NET Native Developer Preview, což je předběžná verze softwaru. Verzi Preview si můžete stáhnout z webu Microsoft Connect (vyžaduje registraci).

Ne všechna selhání vyhledávání metadat v aplikacích vyvinutých pomocí řetězu nástrojů .NET Native způsobí výjimku. Některé se můžou v aplikaci projevit nepředvídatelně. Následující příklad ukazuje porušení přístupu způsobené odkazem na objekt 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]

Pojďme se pokusit vyřešit tuto výjimku pomocí třístupňového přístupu popsaného v části "Ruční řešení chybějících metadat" v části Začínáme.

Co aplikace dělala?

První věc, kterou je třeba poznamenat, je klíčové slovo async na základně zásobníku. Určení toho, co aplikace skutečně prováděla v async metodě, může být problematické, protože zásobník ztratil kontext původního volání a spustil async kód na jiném vlákně. Můžeme ale odvodit, že se aplikace pokouší načíst první stránku. V implementaci pro NavigationArgs.Setup, následující kód způsobil porušení přístupu:

AppViewModel.Current.LayoutVM.PageMap

V tomto případě byla vlastnost LayoutVM na AppViewModel.Currentnull. Nedostatek metadat způsobil jemný rozdíl v chování a vedl k tomu, že vlastnost zůstala neinicializována namísto nastavení, jak aplikace očekávala. Nastavení zarážky v kódu, kde by mělo být LayoutVM inicializováno, může situaci objasnit. Všimněte si však, že LayoutVMtyp je App.Core.ViewModels.Layout.LayoutApplicationVM. Jediná direktiva metadat, která dosud existuje v souboru rd.xml, je:

<Namespace Name="App.ViewModels" Browse="Required Public" Dynamic="Required Public" />

Pravděpodobným důvodem selhání je, že App.Core.ViewModels.Layout.LayoutApplicationVM chybí metadata, protože se nachází v jiném jmenném prostoru.

V tomto případě přidání direktivy modulu runtime pro App.Core.ViewModels vyřešilo problém. Původní příčinou bylo volání rozhraní API metody Type.GetType(String), která vrátila null, a aplikace problém tiše ignorovala, dokud nedošlo k pádu aplikace.

V dynamickém programování je dobrým postupem při použití reflexních API v rámci .NET Native použít přetížení Type.GetType, která vyvolají výjimku při selhání.

Jedná se o izolovaný případ?

Při použití App.Core.ViewModelsmohou nastat i jiné problémy . Musíte se rozhodnout, jestli je vhodné identifikovat a opravit každou chybějící výjimku metadat, nebo ušetřit čas a přidat direktivy pro větší třídu typů. Tady může být přidání dynamic metadat App.Core.ViewModels nejlepším přístupem, pokud výsledné zvětšení velikosti výstupního binárního souboru není problémem.

Mohl by se kód přepsat?

Pokud by aplikace použila typeof(LayoutApplicationVM) místo Type.GetType("LayoutApplicationVM"), mohl by řetězec nástrojů zachovat browse metadata. Při vytváření instance typu by však stále nebyla vytvořena metadata invoke, což by vedlo k výjimce MissingMetadataException. Pokud chcete této výjimce zabránit, musíte přidat direktivu modulu runtime pro obor názvů nebo typ, který určuje zásadu dynamic. Informace o direktivách modulu runtime naleznete v tématu Direktivy modulu runtime (rd.xml) Referenční informace o konfiguračním souboru.

Viz také