.NET 11 Preview 1: Novidades no Runtime

O runtime do .NET 11 começou a tomar forma em 10 de fevereiro de 2026, quando a Microsoft publicou o primeiro preview da nova versão. Isso aconteceu poucos meses depois do lançamento do .NET 10 como versão LTS, em novembro de 2025.

Como acompanho de perto a evolução da plataforma, considero fundamental analisar o que chega ao runtime. Afinal, ele é o alicerce sobre o qual todas as nossas aplicações são construídas.

O ciclo do .NET 11

O .NET 11 será uma versão STS (Standard Term Support), com lançamento previsto para novembro de 2026. Desde o .NET 9, versões STS recebem 24 meses de suporte, então o .NET 11 deve ser suportado até novembro de 2028.

Este primeiro preview já traz mudanças relevantes no runtime do .NET 11, com impacto direto em performance e em novas plataformas. Ao mesmo tempo, as próprias notas de versão avisam que vários recursos ainda estão em andamento.

No vídeo abaixo, comento as principais novidades deste preview.

Runtime async no runtime do .NET 11

A funcionalidade mais significativa deste preview é o runtime async, uma nova infraestrutura em nível de runtime para métodos assíncronos. Não se trata de uma otimização incremental, mas de uma reformulação de como a plataforma executa código async.

Hoje, o compilador C# transforma cada método async em uma state machine. Com o runtime async, o próprio runtime passa a gerenciar a suspensão e a retomada desses métodos.

Objetivo do runtime async

Segundo as notas de versão oficiais do runtime, o objetivo é melhorar ferramental e performance em caminhos com uso intenso de código assíncrono. Na prática, APIs, serviços de mensageria e acesso a dados, que usam async e await em todo lugar, são os maiores candidatos a ganhar.

A infraestrutura inclui configuração, diagnóstico e suporte a AOT. Por isso, a novidade foi pensada desde o desenvolvimento até a produção.

O que mudou no Preview 1

O suporte do CoreCLR ao runtime async vem habilitado por padrão neste preview. Ou seja, não é mais preciso configurar variáveis de ambiente para que o runtime entenda métodos compilados nesse modelo.

Além disso, o NativeAOT já consegue compilar código runtime async, incluindo suporte a continuações e à infraestrutura do toolchain. Por outro lado, nenhuma biblioteca base do runtime foi compilada com runtime async no Preview 1, algo que a Microsoft prevê mudar nos próximos previews.

Como experimentar o runtime async

Se você apenas executa aplicações .NET, não precisa fazer nada. Contudo, para compilar o seu próprio código no novo modelo, é preciso habilitar recursos de preview e ativar o recurso no compilador.

<PropertyGroup>
  <TargetFramework>net11.0</TargetFramework>
  <!-- Necessário no Preview 1 para usar runtime async -->
  <EnablePreviewFeatures>true</EnablePreviewFeatures>
  <Features>$(Features);runtime-async=on</Features>
</PropertyGroup>

Com isso, o compilador deixa de gerar a state machine e delega o trabalho ao runtime do .NET 11. Para quem usa NativeAOT, a mesma configuração vale, já que o toolchain tem suporte básico desde este preview.

// Nenhuma mudança de código é necessária: o mesmo async/await
// passa a ser executado pela infraestrutura do runtime
public sealed class OrderService(HttpClient httpClient)
{
    public async Task<string> GetOrderAsync(int orderId)
    {
        var response = await httpClient.GetAsync($"/api/orders/{orderId}");
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsStringAsync();
    }
}

O detalhe importante é que o código-fonte continua igual. Portanto, avaliar o impacto real em um projeto exige apenas mudar o arquivo de projeto e medir.

Minha sugestão é rodar o mesmo benchmark com e sem o recurso, usando o BenchmarkDotNet. Dessa forma, você compara alocações e tempo de execução em cenários que representam a sua aplicação, e não apenas em exemplos sintéticos.

WebAssembly no runtime do .NET 11

Outra mudança empolgante é o início do trabalho para levar o CoreCLR ao WebAssembly. Historicamente, o .NET no navegador usa o runtime Mono, que oferece um bom equilíbrio entre tamanho e funcionalidade.

O CoreCLR, por sua vez, traz todo o ecossistema de otimizações do runtime principal do .NET. No contexto do navegador, isso pode significar ganhos importantes para aplicações Blazor WebAssembly no futuro.

Estado atual no Preview 1

É importante ter expectativas corretas. As notas de versão descrevem o trabalho como fundacional e deixam claro que ele ainda não está pronto para uso geral no Preview 1.

Como parte desse esforço, o runtime do .NET 11 começa a trazer um RyuJIT voltado para WASM, que será usado em compilação AOT. Assim, a equipe prepara o terreno para que o navegador execute o mesmo pipeline de otimização usado em servidores.

O que isso significa para o Blazor

Essa mudança não invalida o Mono no WebAssembly de imediato. Em vez disso, a estratégia é evoluir aos poucos, até que o CoreCLR esteja maduro para assumir esse papel.

Se você trabalha com Blazor, vale acompanhar o tema de perto. No artigo sobre o futuro do Blazor no .NET 11, discuto o que essa migração muda para quem desenvolve para o navegador.

Interpretador no runtime do .NET 11

O interpretador do CoreCLR também recebeu atenção neste preview. O objetivo é levar o CoreCLR a plataformas que não permitem geração de código em tempo de execução, como WebAssembly e iOS.

Em plataformas assim, um compilador JIT não pode emitir código de máquina durante a execução. Por isso, um interpretador robusto é a peça que permite rodar o runtime completo nesses ambientes.

Assim como no caso do WebAssembly, a Microsoft classifica o trabalho como fundacional e ainda não pronto para uso geral. Mesmo assim, ele se conecta diretamente ao runtime async e à migração de outras cargas para o CoreCLR, como discuto em .NET MAUI migra para o CoreCLR no .NET 11.

Do ponto de vista prático, um interpretador maduro também ajuda em cenários de prototipagem e em ambientes onde o JIT não é possível ou desejável. Em outras palavras, ele amplia o alcance do runtime do .NET 11 sem exigir mudanças no seu código.

JIT no runtime do .NET 11

A equipe do .NET mostra neste preview um foco claro em otimizações direcionadas. Individualmente, elas parecem pequenas, mas o efeito somado aparece em aplicações reais.

Otimizações gerais do JIT

As notas de versão listam um conjunto de mudanças voltadas para inicialização, laços e chamadas:

  • o limite de métodos do Multicore JIT aumentou, o que melhora a inicialização de aplicações grandes;
  • o zeramento de memória de stackalloc no Arm64 ficou mais enxuto;
  • a análise de variáveis de indução foi generalizada, abrindo espaço para mais otimizações de laço;
  • bitfields passam a ser extraídos direto dos registradores de parâmetro em mais casos;
  • structs promovidas passam sempre por FIELD_LIST, removendo restrições antigas do backend.

Desvirtualização de métodos genéricos

A mudança mais visível para quem escreve C# é a desvirtualização de métodos virtuais genéricos não compartilhados. Quando o JIT descobre qual implementação será chamada, ele elimina o custo da chamada virtual e, mais importante, habilita inlining.

public interface IProcessor
{
    void Execute();
}

public sealed class GenericProcessor<T> where T : IProcessor
{
    public void Process(T processor)
    {
        // Pode ser desvirtualizado e até sofrer inlining
        processor.Execute();
    }
}

Na prática, código com uso intenso de generics, como pipelines de processamento e bibliotecas de infraestrutura, tende a ganhar sem nenhuma alteração.

Vetores escaláveis experimentais no Arm64

O preview também introduz o TYP_SIMD como tipo experimental do JIT para Vector<T> no Arm64. O recurso fica atrás da variável de ambiente DOTNET_JitUseScalableVectorT=1.

Trata-se de um passo habilitador para trabalhos futuros com vetores escaláveis. Para quem processa dados vetoriais em Arm64, como em servidores AWS Graviton ou dispositivos móveis, isso pode virar ganhos relevantes nas próximas versões.

Heap hard limit do GC em 32 bits

Uma mudança importante no runtime do .NET 11 para cenários específicos é o suporte ao heap hard limit do GC em processos de 32 bits. Antes, esse recurso só existia para processos de 64 bits.

O heap hard limit define um teto para o tamanho do heap gerenciado. Com isso, você ganha controle operacional sobre o crescimento de memória em ambientes restritos, como:

  • aplicações legadas de 32 bits que ainda precisam ser mantidas;
  • ambientes em contêiner, onde o controle de memória é crítico;
  • sistemas embarcados com pouca memória disponível;
  • hospedagens compartilhadas com limites de recursos.

A configuração pode ficar no runtimeconfig.template.json do projeto, como no exemplo abaixo, que limita o heap a 256 MB.

{
  "configProperties": {
    "System.GC.HeapHardLimit": 268435456
  }
}

Também é possível usar a variável de ambiente DOTNET_GCHeapHardLimit, com o valor em hexadecimal. Se quiser revisar como o coletor funciona, recomendo o artigo sobre o garbage collector em C#.

Em processos de 32 bits, onde o espaço de endereçamento já é naturalmente limitado, esse controle evita que o heap cresça até causar falhas de memória.

Subsistema de espera gerenciado no runtime do .NET 11

Uma mudança arquitetural relevante é a migração do CoreCLR para o subsistema de espera gerenciado compartilhado. Ela parece distante do dia a dia, mas tem implicações na forma como o runtime sincroniza threads.

Tradicionalmente, o CoreCLR dependia do caminho de espera da PAL (Platform Abstraction Layer), baseado em Win32, para código gerenciado. Agora, o runtime do .NET 11 reduz essa dependência e centraliza a lógica de sincronização.

Os benefícios esperados incluem:

  • comportamento mais consistente entre plataformas;
  • menos código de sincronização específico de cada sistema operacional;
  • melhor manutenção e testabilidade do runtime;
  • espaço para otimizar primitivas de sincronização.

Além disso, a lógica de mutex compartilhado entre processos foi portada para código gerenciado. Esses mutexes coordenam várias instâncias de uma aplicação que disputam o mesmo recurso, então trazê-los para código gerenciado segue a mesma estratégia.

NativeAOT e Mono no runtime do .NET 11

O NativeAOT também recebeu melhorias operacionais. O Thread.Interrupt passou a funcionar no NativeAOT para Windows, e executáveis NativeAOT ganharam limites maiores de descritores de arquivo.

Do mesmo modo, a nova variável DOTNET_DbgCreateDumpToolPath permite localizar o createdump quando ele não acompanha o runtime. Isso facilita a coleta de dumps em produção.

Para quem publica serviços com NativeAOT em contêineres, essas mudanças reduzem atritos de operação. Afinal, diagnóstico e limites de recursos costumam ser os pontos que mais geram dúvidas ao migrar do JIT para AOT.

No Mono, há um gancho para exceções não tratadas em finalizadores. Além disso, o bitmap de interfaces comprimido passou a ser o padrão, com configuração para controlar a adoção.

RISC-V e s390x no runtime do .NET 11

O preview também traz trabalho de habilitação para as arquiteturas RISC-V e s390x. Embora não sejam comuns em aplicações corporativas típicas, elas mostram o compromisso de tornar o .NET realmente multiplataforma.

O RISC-V é uma arquitetura aberta que ganha tração em sistemas embarcados e edge computing. Neste preview, o runtime do .NET 11 adiciona suporte inicial à extensão "C", de instruções comprimidas, e à extensão Zbs, de instruções de bit único.

Já a s390x, usada em mainframes IBM, recebeu um fallback de SIMD para gerações mais antigas. Assim, executar .NET moderno em mainframes facilita estratégias de modernização gradual.

Impacto prático do Preview 1

Analisando este primeiro preview de forma prática, vejo um padrão claro em três frentes: performance, alcance de plataforma e maturidade arquitetural.

As melhorias de performance seguem uma estratégia coerente, tanto para alto throughput quanto para ambientes restritos. Ao mesmo tempo, o foco em WebAssembly e no interpretador mostra atenção a casos de uso emergentes.

Mudanças como o subsistema de espera gerenciado não aparecem no dia a dia. Ainda assim, elas criam uma base mais sólida para as próximas evoluções do runtime do .NET 11.

Como testar o runtime do .NET 11

Esta é uma versão preview, destinada a testes e avaliação. Por isso, não recomendo usá-la em produção neste momento.

No entanto, vale muito experimentar as novidades em ambientes de desenvolvimento para:

  1. avaliar o impacto real das melhorias de performance nos seus cenários;
  2. identificar problemas de compatibilidade antes da versão final;
  3. se familiarizar com recursos como o runtime async;
  4. enviar feedback que pode influenciar o desenvolvimento.

O SDK está disponível na página oficial de download do .NET 11. No Windows, use o Visual Studio 2026 Insiders, ou então o Visual Studio Code com a extensão C# Dev Kit como alternativa multiplataforma.

Para acompanhar a evolução, veja também as novidades de runtime do .NET 11 Preview 3, em que o runtime async deixa de exigir o opt-in de preview.

Conclusão

O Preview 1 mostra que a plataforma continua evoluindo de forma significativa. As mudanças no runtime do .NET 11 são técnicas, mas têm potencial de impacto prático em praticamente todas as aplicações.

O runtime async promete melhorar cenários assíncronos, que estão em todo lugar. Já o CoreCLR no WebAssembly e o interpretador preparam o terreno para levar o runtime completo a novas plataformas.

Fico entusiasmado com a direção da plataforma, que equilibra inovação e estabilidade, performance e alcance. Continuarei acompanhando os próximos previews, especialmente para ver como esses recursos evoluem com o feedback da comunidade.

Encorajo você a fazer o mesmo. Afinal, a nossa participação neste processo ajuda a moldar a plataforma que usamos todos os dias.

FAQ

O que é o runtime async do .NET 11?

É uma infraestrutura em nível de runtime para métodos assíncronos, que substitui a state machine gerada pelo compilador. O objetivo é melhorar performance e diagnóstico em código com muito async.

Preciso mudar meu código para usar o runtime async?

Não. No Preview 1, basta habilitar EnablePreviewFeatures e adicionar runtime-async=on em Features no arquivo de projeto.

O Blazor WebAssembly já roda sobre CoreCLR no Preview 1?

Não. O suporte do CoreCLR ao WebAssembly é fundacional neste preview e ainda não está pronto para uso geral.

Por quanto tempo o .NET 11 terá suporte?

O .NET 11 é STS e recebe 24 meses de suporte, de novembro de 2026 a novembro de 2028.

Posso usar o .NET 11 Preview 1 em produção?

Não é recomendado. Previews servem para testes e avaliação, e os recursos ainda podem mudar até o lançamento final.