Compartilhar via


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

Observação

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

Nem todas as falhas de pesquisa de metadados em aplicativos desenvolvidos usando a cadeia de ferramentas .NET Native resultam em uma exceção. Alguns podem se manifestar de maneiras 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 metadados ausentes manualmente" da "Introdução" .

O que o aplicativo estava fazendo?

A primeira coisa a observar é o mecanismo de palavras-chave async na base da pilha. Determinar o que o aplicativo estava realmente fazendo em um async método pode ser problemático, pois a pilha perdeu o contexto da chamada de origem e executou o async código em um thread diferente. No entanto, podemos deduzir que o aplicativo está tentando carregar sua primeira página. Na implementação para NavigationArgs.Setup, o código a seguir causou a violação de acesso:

AppViewModel.Current.LayoutVM.PageMap

Nesse caso, a propriedade LayoutVM no AppViewModel.Current foi nulo. Alguma ausência de metadados causou uma diferença de comportamento sutil e resultou em uma propriedade não inicializada em vez de definida, como o aplicativo esperava. Definir um ponto de interrupção no código em que LayoutVM deveria ter sido inicializado pode esclarecer a situação. No entanto, observe que o tipo de LayoutVMé App.Core.ViewModels.Layout.LayoutApplicationVM. A única diretiva de metadados presente até agora no arquivo rd.xml é:

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

Um provável candidato para a falha é que App.Core.ViewModels.Layout.LayoutApplicationVM está faltando metadados devido a ele(la) estar em um namespace distinto.

Nesse caso, adicionar uma diretiva de runtime para App.Core.ViewModels resolver o problema. A causa raiz foi uma chamada à API para o Type.GetType(String) método que retornou nulo 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 é utilizar as sobrecargas de Type.GetType que lançam uma exceção em caso de falha.

É um caso isolado?

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 teria criado metadados , o que teria levado a uma exceção MissingMetadataException ao instanciar o tipo. Para evitar a exceção, você ainda teria que adicionar uma diretiva de runtime para o namespace ou o tipo que especifica a dynamic política. Para obter informações sobre diretivas de tempo de execução, consulte a referência do arquivo de configuração de diretivas de tempo de execução () (rd.xml).

Consulte também