Compartilhar via


Exemplo: solucionando problemas de programação dinâmica

Observação

Este tópico refere-se ao Developer Preview do .NET Nativo, que é um software em pré-lançamento. Você pode baixar a versão prévia do site Microsoft Connect (registro obrigatório).

Nem todas as falhas de pesquisa de metadados em aplicativos desenvolvidos usando a cadeia de ferramentas do .NET Native resultam em uma exceção. Alguns podem manifestar-se de formas imprevisíveis em um aplicativo. O exemplo a seguir mostra uma violação de acesso causada pela referência a um objeto nulo:

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]

Vamos tentar solucionar essa exceção usando a abordagem de três etapas descrita na seção “Resolver manualmente os metadados ausentes” da Introdução.

O que o aplicativo estava fazendo?

A primeira coisa a observar é o maquinário da palavra-chave do async na base da pilha. Determinar o que o aplicativo fazia em método async pode ser problemático, porque a pilha perde o contexto da chamada de origem e executa o código async em um thread diferente. No entanto, podemos deduzir que o aplicativo está tentando carregar sua primeira página. Na implementação de NavigationArgs.Setup, o seguinte código causou a violação de acesso:

AppViewModel.Current.LayoutVM.PageMap

Nesta instância, a propriedade LayoutVM em AppViewModel.Current era null. A ausência de metadados causou uma diferença de comportamento sutil e resultou em uma propriedade sendo não inicializada em vez do conjunto, como o aplicativo esperava. Definir um ponto de interrupção no código onde LayoutVM deveria ter sido inicializado poderá esclarecer a situação. No entanto, observe que LayoutVMo tipo App.Core.ViewModels.Layout.LayoutApplicationVMde . A única diretiva de metadados presente até agora no arquivo rd.xml é:

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

O motivo mais provável da falha é que metadados estão faltando em App.Core.ViewModels.Layout.LayoutApplicationVM porque ela está em um namespace diferente.

Nesse caso, adicionar uma diretiva de runtime para App.Core.ViewModels resolveu o problema. A causa raiz foi uma chamada à API ao método Type.GetType(String) que retornou null e o aplicativo ignorou silenciosamente o problema até que ocorreu uma falha.

Na programação dinâmica, uma boa prática ao usar APIs de reflexão no .NET Native é usar as Type.GetType sobrecargas que geram uma exceção em caso de falha.

Esta é uma ocorrência isolada?

Outros problemas também podem surgir ao usar App.Core.ViewModels. Você deve decidir se vale a pena identificar e corrigir cada exceção de metadados ausente ou economizar tempo e adicionar diretivas para uma classe maior de tipos. Aqui, adicionar dynamic metadados para App.Core.ViewModels pode ser a melhor abordagem se o aumento de tamanho resultante do binário de saída não for um problema.

O código pode ser reescrito?

Se o aplicativo tivesse usado typeof(LayoutApplicationVM) em vez de Type.GetType("LayoutApplicationVM"), a cadeia de ferramentas poderia ter preservado os metadados browse. No entanto, ele ainda não criaria os metadados de invoke, o que levaria a uma exceção MissingMetadataException ao instanciar o tipo. Para evitar a exceção, ainda seria necessário adicionar uma diretiva de runtime para o namespace ou o tipo que especifica a política dynamic. Para obter informações sobre as diretivas de runtime, consulte a Referência do arquivo de configuração das diretivas de runtime (rd.xml).

Confira também