Поделиться через


Пример. Устранение неполадок динамического программирования

Замечание

В этом разделе рассматривается .NET Native Developer Preview, которое является предварительным программным обеспечением. Вы можете скачать предварительный просмотр с веб-сайта Microsoft Connect (требуется регистрация).

Не все ошибки поиска метаданных в приложениях, разработанных с помощью цепочки инструментов .NET Native, приводят к исключению. Некоторые могут манифестироваться непредсказуемыми способами в приложении. В следующем примере показано нарушение доступа, вызванное ссылкой на пустой объект:

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]

Давайте попытаемся устранить это исключение с помощью трехэтапного подхода, описанного в разделе "Устранение отсутствующих метаданных вручную" из Приступая к работе.

Что делает приложение?

Первое, что следует отметить, это механизм ключевого слова async, расположенный у основания стека. Определение того, что приложение действительно делает в методе async может быть проблематичным, так как стек потерял контекст исходного вызова и выполнял async код в другом потоке. Однако мы можем определить, что приложение пытается загрузить свою первую страницу. В реализации для NavigationArgs.Setupследующий код вызвал нарушение доступа:

AppViewModel.Current.LayoutVM.PageMap

В данном случае свойство LayoutVM на AppViewModel.Current было null. Отсутствие части метаданных привело к незначительному изменению в поведении и привело к тому, что свойство не было инициализировано, вместо того чтобы быть установленным, как ожидалось приложением. Установка точки останова в коде, где LayoutVM следовало бы инициализировать, может пролить свет на ситуацию. Однако обратите внимание, что LayoutVMявляется типом App.Core.ViewModels.Layout.LayoutApplicationVM. Единственная директива метаданных, представленная до сих пор в файле rd.xml, — это:

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

Вероятной причиной сбоя является отсутствие метаданных у App.Core.ViewModels.Layout.LayoutApplicationVM, поскольку она находится в другом пространстве имён.

В этом случае добавление директивы времени выполнения для App.Core.ViewModels устранило проблему. Первопричиной был вызов API метода Type.GetType(String), возвращающего null, и приложение автоматически проигнорировало проблему до сбоя.

В динамическом программировании при использовании API рефлексии в .NET Native рекомендуется задействовать перегрузки Type.GetType, которые генерируют исключение в случае ошибки.

Это изолированный случай?

Другие проблемы также могут возникнуть при использовании App.Core.ViewModels. Необходимо решить, следует ли определять и исправлять все отсутствующие исключения метаданных, а также сохранять время и добавлять директивы для большего класса типов. Здесь добавление метаданных dynamic для App.Core.ViewModels может быть наилучшим подходом, если увеличение размера результирующего двоичного файла не является проблемой.

Может ли код быть перезаписан?

Если приложение использовало typeof(LayoutApplicationVM) вместо Type.GetType("LayoutApplicationVM"), цепочка инструментов могла сохранить browse метаданные. Тем не менее, он по-прежнему не создал бы invoke метаданных, что привело бы к missingMetadataException исключение при создании экземпляра типа. Чтобы предотвратить возникновение исключения, необходимо добавить директиву среды выполнения для пространства имен или типа, которые определяют политику dynamic. Для получения информации о директивах среды выполнения см. справочник по файлу конфигурации "Директивы среды выполнения" (rd.xml) ().

См. также