Hoje, estamos anunciando o .NET Core 3.0 Preview 6 . Ele inclui atualizações para compilar montagens para uma inicialização aprimorada, otimizando aplicativos para o tamanho com melhorias no vinculador e EventPipe. Também lançamos novas imagens do Docker para Alpine no ARM64.

Atualização de WPF e Windows Forms
A equipe do WPF concluiu a publicação da maior parte da base de código do WPF no GitHub . De fato, eles apenas publicaram fonte para quinze assembléias . Para qualquer pessoa familiarizada com o WPF, os nomes de assembly devem ser muito familiares.
Em alguns casos, os testes ainda estão no backlog para serem publicados antes ou no 3.0 GA. Dito isto, a presença de todo esse código deve permitir que a comunidade do WPF participe totalmente da realização de alterações no WPF. É óbvio, lendo alguns dos problemas do GitHub, que a comunidade tem sua própria lista de pendências que estava esperando para realizar. Tema escuro, talvez?
Imagens do Docker alpino
As imagens do Docker agora estão disponíveis para o .NET Core e o ASP.NET Core no ARM64. Eles estavam anteriormente disponíveis apenas para x64.
As imagens a seguir podem ser usadas em um Dockerfile
ou com o docker pull
, conforme demonstrado abaixo:
docker pull mcr.microsoft.com/dotnet/core/runtime:3.0-alpine-arm64v8
docker pull mcr.microsoft.com/dotnet/core/aspnet:3.0-alpine-arm64v8
Melhorias no canal de eventos
O Event Pipe agora suporta várias sessões. Isso significa que você pode consumir eventos com o EventListener em processo e simultaneamente ter clientes de canal de eventos fora de processo.
Novos contadores de desempenho adicionados:
- % De tempo no GC
- Tamanho da pilha da geração 0
- Tamanho da pilha da geração 1
- Tamanho da pilha da geração 2
- Tamanho da pilha LOH
- Taxa de alocação
- Número de montagens carregadas
- Número de threads ThreadPool
- Taxa de Contenção de Bloqueio do Monitor
- Fila de itens de trabalho ThreadPool
- Taxa de Itens de Trabalho Concluídos ThreadPool
A conexão do Profiler agora é implementada usando a mesma infraestrutura de Event Pipe.
Consulte Jogando com contadores de David Fowler para ter uma idéia do que você pode fazer com o canal de eventos para executar suas próprias investigações de desempenho ou apenas monitorar o status do aplicativo.
Consulte dotnet-counters para instalar a ferramenta dotnet-counters.
Otimize seus aplicativos .NET Core com imagens ReadyToRun
Você pode melhorar o tempo de inicialização do aplicativo .NET Core compilando os assemblies de aplicativos no formato ReadyToRun (R2R). R2R é uma forma de compilação antecipada (AOT).
Os binários R2R aprimoram o desempenho da inicialização, reduzindo a quantidade de trabalho que o JIT precisa para executar o carregamento do aplicativo. Os binários contêm código nativo semelhante ao que o JIT produziria, dando ao JIT umas férias quando o desempenho mais importa (na inicialização). Os binários R2R são maiores porque contêm código de linguagem intermediária (IL), que ainda é necessário para alguns cenários, e a versão nativa do mesmo código, para melhorar a inicialização.
O R2R é suportado com o .NET Core 3.0. Ele não pode ser usado com versões anteriores do .NET Core.
Amostra de números de desempenho
A seguir, são apresentados os números de desempenho coletados usando um aplicativo WPF de amostra . O aplicativo foi publicado como independente e não usou o vinculador de montagem (abordado posteriormente nesta postagem).
Aplicativo somente para IL:
- Tempo de inicialização: 1,9 segundos
- Uso de memória: 69,1 MB
- Tamanho do aplicativo: 150 MB
Com imagens ReadyToRun:
- Tempo de inicialização: 1,3 segundos.
- Uso de memória: 55,7 MB
- Tamanho do aplicativo: 156 MB
Imagens ReadyToRun, explicadas
Você pode R2R compilar bibliotecas e binários de aplicativos. No momento, as bibliotecas podem ser compiladas apenas como R2R como parte de um aplicativo, não para entrega como um pacote NuGet. Gostaríamos de receber mais feedback sobre se esse cenário é importante.
Os assemblies de compilação AOT estão disponíveis como um conceito com o .NET há muito tempo, voltando ao .NET Framework e ao NGEN . O NGEN tem uma desvantagem importante: a compilação deve ser feita nas máquinas clientes, usando a ferramenta NGEN. Não é possível gerar imagens NGEN como parte da compilação do aplicativo.
Digite o .NET Core. Ele vem com o crossgen , que produz imagens nativas em um formato mais novo chamado ReadyToRun . O nome descreve sua principal proposta de valor, que é que essas imagens nativas podem ser construídas como parte de sua construção e estão "prontas para execução" sem nenhum trabalho adicional nas máquinas clientes. Essa é uma grande melhoria e também uma vitória importante para as mudanças climáticas.
Em termos de compatibilidade, as imagens ReadyToRun são semelhantes aos assemblies IL, com algumas diferenças importantes.
- Assemblies IL contêm apenas código IL . Eles podem ser executados em qualquer tempo de execução que suporte a estrutura de destino fornecida para esse assembly. Por exemplo, um assembly
netstandard2.0
pode ser executado no .NET Framework 4.6+ e .NET Core 2.0+, em qualquer sistema operacional suportado (Windows, macOS, Linux) e arquitetura (Intel, ARM, 32 bits, 64 bits). - Os assemblies R2R contêm IL e código nativo. Eles são compilados para uma versão de tempo de execução mínima específica do .NET Core e o ambiente de tempo de execução (RID). Por exemplo, um assembly
netstandard2.0
pode ser compilado com o R2R para .NET Core 3.0 e Linux x64. Ele só será utilizável nessa configuração ou em uma configuração compatível (como .NET Core 3.1 ou .NET Core 5.0, no Linux x64), porque contém código nativo que pode ser usado apenas nesse ambiente de tempo de execução.
Instruções
A compilação ReadyToRun é um recurso de inclusão e publicação somente. Lançamos uma versão prévia com o .NET Core 3.0 Preview 5.
Para habilitar a compilação ReadyToRun, você deve:
- Defina a propriedade
PublishReadyToRun
como true
. - Publique usando um
RuntimeIdentifier
explícito.
Nota: Quando os assemblies de aplicativos são compilados, o código nativo produzido é específico da plataforma e da arquitetura (é por isso que você precisa especificar um RuntimeIdentifier válido ao publicar).
Aqui está um exemplo:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> <PublishReadyToRun>true</PublishReadyToRun> </PropertyGroup> </Project>
E publique usando o seguinte comando:
dotnet publish -r win-x64 -c Release
Nota: O RuntimeIdentifier
também pode ser definido no arquivo do projeto.
Nota: No momento, o ReadyToRun é suportado apenas para aplicativos independentes . Ele será ativado para aplicativos dependentes da estrutura em uma visualização posterior.
A geração de símbolo nativo pode ser ativada definindo a propriedade PublishReadyToRunEmitSymbols
como true
no seu projeto. Você não precisa gerar símbolos nativos para fins de depuração. Esses símbolos são úteis apenas para fins de criação de perfil.
Atualmente, o SDK suporta uma maneira de excluir certos assemblies da compilação em imagens ReadyToRun. Isso pode ser útil para casos em que determinados conjuntos realmente não precisam ser otimizados para desempenho. Isso pode ajudar a reduzir o tamanho do aplicativo. Também pode ser uma solução útil para casos em que o compilador ReadyToRun falha ao compilar um determinado assembly. A exclusão é feita usando o grupo de itens PublishReadyToRunExclude. Exemplo:
<ItemGroup> <PublishReadyToRunExclude Include="FilenameOfAssemblyToExclude.dll" /> </ItemGroup>
Compilações entre plataformas / arquitetura
Atualmente, o compilador ReadyToRun não oferece suporte à segmentação cruzada. Você precisa compilar em um determinado destino. Por exemplo, se você deseja imagens R2R para Windows x64, é necessário executar o comando de publicação nesse ambiente.
Exceções a isso:
- O Windows x64 pode ser usado para compilar imagens do Windows ARM32, ARM64 e x86.
- O Windows x86 pode ser usado para compilar imagens do Windows ARM32.
- O Linux x64 pode ser usado para compilar imagens Linux ARM32 e ARM64.
Ligação de montagem
O .NET core 3.0 SDK vem com uma ferramenta que pode reduzir o tamanho dos aplicativos analisando a IL e aparando os assemblies não utilizados.
Com o .NET Core, sempre foi possível publicar aplicativos independentes que incluem tudo o necessário para executar seu código, sem exigir que o .NET seja instalado no destino de implantação. Em alguns casos, o aplicativo requer apenas um pequeno subconjunto da estrutura para funcionar e pode potencialmente ser muito menor, incluindo apenas as bibliotecas usadas.
Usamos o vinculador de IL para varrer a IL do seu aplicativo para detectar qual código é realmente necessário e, em seguida, aparar bibliotecas de estrutura não utilizadas. Isso pode reduzir significativamente o tamanho de alguns aplicativos. Normalmente, aplicativos de console pequenos, como ferramentas, se beneficiam mais, pois tendem a usar subconjuntos bastante pequenos da estrutura e geralmente são mais propensos a aparar.
Para usar esta ferramenta, defina PublishTrimmed=true
no seu projeto e publique um aplicativo independente:
dotnet publish -r <rid> -c Release
A saída de publicação incluirá um subconjunto das bibliotecas da estrutura, dependendo do que o código do aplicativo chama. Para um aplicativo helloworld, o vinculador reduz o tamanho de ~ 68MB para ~ 28MB.
Aplicativos ou estruturas (incluindo ASP.NET Core e WPF) que usam reflexão ou recursos dinâmicos relacionados geralmente são interrompidos quando cortados, porque o vinculador não conhece esse comportamento dinâmico e geralmente não pode determinar quais tipos de estrutura serão necessários para reflexão em tempo de execução. Para aparar esses aplicativos, é necessário informar o vinculador sobre todos os tipos necessários para refletir no seu código e em quaisquer pacotes ou estruturas das quais você depende. Certifique-se de testar seus aplicativos após o corte.
Para obter mais informações sobre o IL Linker, consulte a documentação ou visite o repositório mono / linker .
Nota: Nas versões anteriores do .NET Core, o ILLink.Tasks era enviado como um pacote NuGet externo e fornecia muitas das mesmas funcionalidades. Já não é suportado - atualize para o SDK 3.0 mais recente e experimente a nova experiência!
Usando o vinculador e o ReadToRun juntos
O vinculador e o compilador ReadyToRun podem ser usados para o mesmo aplicativo. Em geral, o vinculador torna seu aplicativo menor e, em seguida, o compilador pronto para execução o tornará um pouco maior novamente, mas com um ganho de desempenho significativo. Vale a pena testar em várias configurações para entender o impacto de cada opção.
Nota: dotnet / sdk # 3257 impede que o vinculador e o ReadyToRun sejam usados juntos para aplicativos WPF e Windows Forms. Estamos trabalhando para corrigir isso como parte da versão .NET Core 3.0.
Amostra de hospedagem nativa
A equipe postou recentemente uma amostra de hospedagem nativa . Ele demonstra uma abordagem de práticas recomendadas para hospedar o .NET Core em um aplicativo nativo.
Como parte do .NET Core 3.0, agora expomos a funcionalidade geral aos hosts nativos do .NET Core que anteriormente estavam disponíveis apenas para aplicativos gerenciados pelo .NET Core por meio dos hosts .NET Core fornecidos oficialmente. A funcionalidade está relacionada principalmente ao carregamento de montagem. Essa funcionalidade deve facilitar a produção de hosts nativos que podem aproveitar o conjunto completo de recursos do .NET Core.
Suporte HTTP / 2 no HttpClient
HTTP / 2 é uma revisão importante do protocolo HTTP. Alguns dos recursos notáveis do HTTP / 2 são o suporte à compactação de cabeçalho e fluxos totalmente multiplexados na mesma conexão. Enquanto o HTTP / 2 preserva a semântica do HTTP (cabeçalhos HTTP, métodos, etc.), é uma alteração do HTTP / 1.x na forma como os dados são enquadrados e enviados pela conexão.
HttpClient
agora adiciona suporte para fazer solicitações HTTP / 2. Enquanto o padrão permanece HTTP / 1.1, você pode optar por usar o HTTP / 2 configurando a versão na sua mensagem de solicitação HTTP.
var client = new HttpClient() { BaseAddress = new Uri("https://localhost:5001") };
Como alternativa, você pode usar como padrão o envio de solicitações HTTP / 2, definindo a propriedade DefaultRequestVersion
em HttpClient
.
var client = new HttpClient() { BaseAddress = new Uri("https://localhost:5001"), DefaultRequestVersion = new Version(2, 0) };
Como conseqüência dessa mudança no enquadramento, servidores e clientes precisam negociar a versão do protocolo usada. A ALPN (Application-Layer Protocol Negotiation) é uma extensão TLS que permite ao servidor e ao cliente negociar a versão do protocolo usada como parte do handshake do TLS. Embora seja possível ter conhecimento prévio entre o servidor e o cliente no protocolo, a maioria dos servidores suporta apenas o ALPN como a única maneira de estabelecer uma conexão HTTP / 2. Como tal, o HTTP / 2 é negociado pelo HttpClient
apenas em uma conexão TLS.
Em cenários de desenvolvimento em que servidor e cliente têm conhecimento prévio de que ambos falarão HTTP / 2 sem criptografia, você pode estabelecer uma conexão HTTP / 2 sobre texto não criptografado configurando uma opção AppContext
ou uma variável de ambiente ( DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP2UNENCRYPTEDSUPPORT=1
).
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
Encerramento
Por favor, experimente os novos recursos. Por favor, registre problemas para os bugs ou quaisquer experiências desafiadoras que encontrar. Queremos o feedback! Você também pode arquivar solicitações de recursos, mas elas provavelmente precisarão esperar para serem implementadas até a próxima versão neste momento.
Agora estamos chegando muito perto de estarmos completos para o .NET Core 3.0 e agora estamos migrando o foco da equipe para a qualidade do lançamento. Temos alguns meses de correção de erros e trabalho de desempenho pela frente. Agradecemos seus comentários enquanto trabalhamos nesse processo também.
Nessa nota, em breve mudaremos as ramificações master
nos repositórios do .NET Core para a próxima versão principal, provavelmente após a versão Preview 7 (julho) ou logo após.
Obrigado por experimentar as visualizações do .NET Core 3.0. Agradecemos sua ajuda. Neste ponto, estamos focados em obter um lançamento final em suas mãos.
Richard LanderPM, Equipe .NET