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


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

Примечание.

В этом разделе рассматривается предварительная версия программного обеспечения для разработчиков машинного кода .NET. Предварительную версию можно скачать на веб-сайте 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. Необходимо решить, следует ли определять и исправлять все отсутствующие исключения метаданных, а также сохранять время и добавлять директивы для большего класса типов. Здесь добавление метаданных App.Core.ViewModels может быть лучшим подходом, dynamic если результирующее увеличение размера выходного двоичного файла не является проблемой.

Можно переписать код?

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

См. также