.NET Native — O que isso significa para os Desenvolvedores Universal Windows Platform (UWP)

NetCoders
netcoders
Published in
8 min readOct 6, 2015
UWP

Esse artigo aborda o uso do .NET Native, seus benefícios e o que podemos encontrar durante o desenvolvimento utilizando a plataforma.

O que é o .NET Native?

.NET Native é uma tecnologia de pré-compilação para a construção de Universal Windows Apps no Visual Studio 2015. O conjunto de ferramentas .NET Native irá compilar seus binários IL gerenciados em binários nativos. Cada um dos Universal Windows Apps gerenciados (C# ou VB) irão utilizar essa nova tecnologia. As aplicações automaticamente são compiladas para código nativo antes que eles atinjam os dispositivos onde serão utilizados. Se você gostaria de se aprofundar no funcionamento, eu recomendo ler mais sobre ele no MSDN.

Como o .NET Native afeta eu e o meu aplicativo?

Provavelmente sua performance pode variar, mas para a maioria dos casos seu app vai iniciar mais rápido, terá melhor desempenho e consumir menos recursos do sistema.

  • Melhoria de desempenho de 60% nos tempos de inicialização completa
  • Melhoria de desempenho de 40% nos tempos de inicialização acelerada
  • Menor consumo de memória do seu aplicativo quando compilado nativamente
  • Nenhuma dependência na desktop .NET Runtime instalado no sistema
  • Uma vez que seu aplicativo é compilado nativamente, você obtém os benefícios de desempenho associados com código nativo (Pense no desempenho do C++ )
  • Você ainda pode tirar vantagem das linguagens de programação C# ou VB e as ferramentas que lhes estão associadas
  • Você pode continuar a usar o abrangente e consistente modelo de programação disponível com .NET — com extensivas APIs para escrever a lógica de negócios, gerenciamento de memória interna e manipulação de exceção.

Você consegue o melhor dos dois mundos, a experiência de desenvolvimento gerenciado com desempenho de C++. É ou não é uma coisa excelente?

Diferenças de configuração entre Debug e Release

A Compilação .NET Native é um processo complexo, e que o torna um pouco mais lento quando comparado à clássica compilação do .NET. Os benefícios mencionados acima têm um custo de tempo de compilação. Você poderia escolher compilar nativamente toda vez que você deseja executar o seu aplicativo, mas você passaria mais tempo esperando a compilação terminar. As ferramentas do Visual Studio são projetadas para lidar com isso e criar a experiência de desenvolvedor mais suave possível .

Quando você criar e executar no modo “Debug”, você está executando o código IL contra o CoreCLR encapsulado dentro de seu aplicativo. As compilações do sistema .NET são encapsuladas juntamente com o código do aplicativo, e o aplicativo preenche uma dependência no pacote Microsoft.NET.CoreRuntime (CoreCLR).

Isto significa que você obtém a melhor experiência de desenvolvimento possível — rápida compilação e implantação, rico em depuração e diagnóstico e todas as outras ferramentas que você está acostumado no desenvolvimento .NET.

Quando você alternar para o modo “Release”, por padrão, seu app utiliza a cadeia de ferramentas .NET Native. A partir do momento que o pacote é compilado para binários nativos, o pacote não precisa conter as bibliotecas do framework .NET. Além disso, o pacote é dependente do runtime .NET Native mais recente instalado em oposição ao pacote CoreCLR. O tempo de execução .NET Native no dispositivo sempre será compatível com seu pacote de aplicativos.

A compilação nativa local através da configuração de “Release” permitirá testar seu aplicativo em um ambiente que é parecido com o que seus clientes irão experimentar. É importante testar isto em uma base regular onde você prosseguirá com o desenvolvimento.

Uma boa regra é testar seu app periodicamente durante todo o desenvolvimento para certificar-se de identificar e corrigir quaisquer problemas que podem vir do compilador .NET Native. Não deve haver nenhum problema na maioria dos casos; no entanto, ainda existem algumas coisas que não rodam tão bem com .NET Native. Matrizes dimensionais Four+ são um exemplo disso. Em última análise, seus clientes estarão recebendo a versão .NET nativa compilada do seu aplicativo, por isso é sempre uma boa prática testar essa versão durante todo o desenvolvimento e antes do envio.

Além de certificar-se de que você teste com a compilação.NET nativa, você também pode perceber que a configuração da compilação AnyCPU desapareceu. Com .NET inserido à mistura, a AnyCPU já não é uma configuração de compilação válida porque a compilação nativa é dependente de arquitetura. Uma consequência adicional disso é que quando você empacota seu aplicativo, você deve selecionar todas as três configurações de arquitetura (x86, x64 e ARM) para certificar-se que seu aplicativo é aplicável à maioria dos dispositivos possível. Afinal, esta é a Universal Windows Platform. Por padrão, o Visual Studio irá guiá-lo nesse ponto como mostrado no diagrama abaixo:

NetNative_1

Dito isso, você ainda pode construir bibliotecas e DLLs AnyCPU para ser referenciado no seu app UWP. Esses componentes serão compilados para binários específicos da arquitetura com base na configuração do projeto (.appx) que irá consumi-la.

A última alteração substancial ao seu fluxo de trabalho como resultado do .NET Native é como criar um pacote aceitável para a loja. Uma grande característica do .NET Native é que o compilador é capaz de ser hospedado na nuvem. Quando você cria seu pacote de loja no Visual Studio, dois pacotes são criados — um .appxupload e um .appx de “teste” para “Sideloading”. O .appxupload contém os binários MSIL, bem como uma referência explícita à versão do toolchain .NET Native que seu app consome (referenciado no AppxManifest.xml). Este pacote, então, vai para a loja e é compilado usando exatamente a mesma versão do toolchain.NET Native. Uma vez que o compilador é hospedado na nuvem, ele pode ser iterado para corrigir bugs sem você ter que recompilar seu aplicativo localmente.

NetNative_2

Isso afeta diretamente em duas partes do fluxo de trabalho do desenvolvedor. A primeira é que você como um desenvolvedor já não têm mais acesso ao número de revisão do seu pacote de aplicativo (a quarta). A loja reserva este número como uma maneira para iterar sobre o pacote de app, se por qualquer motivo, o pacote é recompilado na nuvem. Mas não se preocupe, você ainda tem o controle dos outros três números.

A segunda é que você tem que ter cuidado sobre qual pacote você fará o upload para a loja. Desde que a loja faz a compilação nativa para você, você não pode carregar os binários nativos gerados pelo compilador .NET Native local. O fluxo de trabalho do Visual Studio irá guiá-lo através deste processo, assim que você selecionar o pacote certo.

NetNative_3

Quando você usar o assistente de empacotamento do app para criar seus pacotes, você deve certificar-se de selecionar “Sim” quando o Visual Studio perguntar se você quer criar um pacote para enviar para a loja. É recomendado selecionar “Sempre” para a opção “Generate bundle app” (Gerar pacote do aplicativo), pois isso resultará em última análise, em um arquivo único .appxupload que estará pronto para o upload. Para orientação completa sobre como criar um pacote de loja, você pode dar uma olhada em Packaging Universal Windows apps for Windows 10.

Para resumir, as principais alterações ao seu fluxo de trabalho com .NET Native são:

  • Precisará testar seu aplicativo usando a configuração de “Release” regularmente
  • Certificar-se de deixar o número do pacote de revisão como “0” — o Visual Studio não deixa você mudar isso, mas certifique-se que você não mudou em um editor de texto
  • Deve apenas carregar o .appxupload gerado na criação de pacote para a loja — se você carregar o UWP .appx, a loja vai rejeitá-lo com erros

Algumas outras dicas ao utilizar .NET Native

Se você encontrar quaisquer problemas que você suspeita serem causados pelo .NET Native, há uma técnica que você pode usar para ajudar a depurar o problema. As configurações de versão por padrão otimizam o código que perde alguns artefatos usados para a depuração. Como resultado, ao tentar depurar uma configuração de versão pode ocorrer alguns problemas. Ao invés disso, o que você pode fazer é criar uma configuração personalizada e habilitar o toolchain do .NET Native para essa configuração. Certifique-se de não otimizar o código. Mais detalhes sobre isso podem ser encontrados aqui.

Agora que você sabe como depurar problemas, não seria melhor se você pudesse evitá-los desde o início?
O Microsoft.NETNative.Analyzer pode ser instalado em seu aplicativo via NuGet. No console do Gerenciador de pacotes, você pode instalar o pacote através do seguinte comando: “Install-Package Microsoft.NETNative.Analyzer”. Em tempo de desenvolvimento, este analisador lhe dará avisos se seu código não for compatível com o compilador .NET Native. Há uma pequena parte da superfície do .NET, que não é compatível, mas para a maioria dos apps isto nunca será um problema.

Se você está curioso sobre as melhorias de tempo de inicialização do seu aplicativo do .NET Native, você pode tentar medir isso.

Problemas conhecidos e soluções alternativas

Há algumas coisas que devemos manter em mente ao usar o Windows Application Certification Kit (WACK) para testar seus aplicativos:

Quando você executar o WACK em um app UWP que não foi através deste processo de empacotamento, você obterá uma falha nada comum. Algo como:

  • API ExecuteAssembly em uwphost.dll não é suportado para este tipo de aplicação. O App.exe chama essa API.
  • API DllGetActivationFactory de uwphost.dll não é suportado para este tipo de aplicação. O App.exe tem uma exportação que encaminha para esta API.
  • API OpenSemaphore em ap-ms-win-core-synch-11–1–0.dll não é suportado para este tipo de aplicação. O System.Threading.dll chama essa API.
  • API CreateSemaphore em api-ms-win-core-kernel32-legacy-11–1–0.dll não é suportado para este tipo de aplicação. O System.Threading.dll chama essa API.

A correção para esses erros é ter certeza que você está criando seus pacotes corretamente e executando o WACK sobre o pacote correto. Se você seguir estas diretrizes de empacotamento, você nunca encontrará esses problemas.

Aplicativos .NET nativos que usam reflexão podem fazer o WACK falhar com uma falsa referência para o Windows.Networking.Vpn.

Para consertar isso, no arquivo rd.xml no seu Gerenciador de soluções, adicione a seguinte linha e faça o Rebuild:

<Namespace Name=”Windows.Networking.Vpn” Dynamic=”Excluded” Serialize=”Excluded” Browse=”Excluded” Activate=”Excluded” />

Resumo

Todos os usuários do Windows irão se beneficiar com o .NET Native.

As Apps gerenciadas na loja vão começar e rodar mais rápidas.

Os colaboradores terão a experiência de desenvolvimento .NET que estão acostumados com o Visual Studio, e os clientes terão o aumento de desempenho do código nativo.

Se você quiser fornecer feedback, utilize o UserVoice. Se você tem um bug para relatar, você pode fazê-lo através do Connect.

--

--