Novidades do .NET Core 2.2

O .NET Core 2.2 inclui aprimoramentos na implantação do aplicativo, na manipulação de eventos para serviços de runtime, na autenticação de Bancos de Dados SQL do Azure, no desempenho do compilador JIT e na injeção de código antes da execução do método Main.

Novo modo de implantação

A partir do .NET Core 2.2, você pode implantar executáveis dependentes da estrutura, que são arquivos .exe em vez de arquivos .dll. Com uma funcionalidade semelhante às implantações dependentes de estrutura, os FDEs (executáveis dependentes de estrutura) ainda contam com a presença de uma versão compartilhada de todo o sistema do .NET Core para executar. Seu aplicativo contém apenas seu código e quaisquer dependências de terceiros. Ao contrário de implantações dependentes de estrutura, os FDEs são específicos da plataforma.

Esse novo modo de implantação tem a vantagem distinta da criar um executável em vez de uma biblioteca, o que significa que você pode executar seu aplicativo diretamente, sem invocar dotnet primeiro.

Núcleo

Manipulação de eventos nos serviços de runtime

Muitas vezes, convém monitorar o uso dos serviços de runtime do seu aplicativo, como o GC, o JIT e o ThreadPool, para entender como eles afetam seu aplicativo. Em sistemas Windows, isso normalmente é feito pelo monitorando de eventos ETW do processo atual. Embora isso continue funcionando bem, nem sempre é possível usar ETW se você estiver executando em um ambiente com poucos privilégios, ou no Linux ou macOS.

A partir do .NET Core 2.2, os eventos de CoreCLR podem ser consumidos usando a classe System.Diagnostics.Tracing.EventListener. Esses eventos descrevem o comportamento desses serviços de runtime como GC, JIT, ThreadPool e interoperabilidade. Esses são os mesmos eventos são expostos como parte do provedor ETW CoreCLR. Isso permite que os aplicativos consumam esses eventos ou usem um mecanismo de transporte para enviá-los para um serviço de agregação de telemetria. Veja como assinar eventos no exemplo de código a seguir:

internal sealed class SimpleEventListener : EventListener
{
    // Called whenever an EventSource is created.
    protected override void OnEventSourceCreated(EventSource eventSource)
    {
        // Watch for the .NET runtime EventSource and enable all of its events.
        if (eventSource.Name.Equals("Microsoft-Windows-DotNETRuntime"))
        {
            EnableEvents(eventSource, EventLevel.Verbose, (EventKeywords)(-1));
        }
    }

    // Called whenever an event is written.
    protected override void OnEventWritten(EventWrittenEventArgs eventData)
    {
        // Write the contents of the event to the console.
        Console.WriteLine($"ThreadID = {eventData.OSThreadId} ID = {eventData.EventId} Name = {eventData.EventName}");
        for (int i = 0; i < eventData.Payload.Count; i++)
        {
            string payloadString = eventData.Payload[i]?.ToString() ?? string.Empty;
            Console.WriteLine($"\tName = \"{eventData.PayloadNames[i]}\" Value = \"{payloadString}\"");
        }
        Console.WriteLine("\n");
    }
}

Além disso, o .NET Core 2.2 adiciona as duas propriedades a seguir à classe EventWrittenEventArgs para fornecer informações adicionais sobre eventos ETW:

Dados

Autenticação do AAD para Bancos de Dados SQL do Azure com a propriedade SqlConnection.AccessToken

A partir do .NET Core 2.2, um token de acesso emitido pelo Azure Active Directory pode ser usado para autenticar em um Banco de Dados SQL do Azure. Para dar suporte a tokens de acesso, a propriedade AccessToken foi adicionada à classe SqlConnection. Para aproveitar a autenticação do AAD, baixe a versão 4.6 do pacote NuGet System.Data.SqlClient. Para usar o recurso, obtenha o valor do token de acesso usando a Biblioteca de Autenticação do Active Directory para .NET contida no pacote NuGet Microsoft.IdentityModel.Clients.ActiveDirectory.

Melhorias do compilador JIT

A compilação em camadas permanece um recurso ativado mediante consentimento

No .NET Core 2.1, o compilador JIT implementou uma nova tecnologia compiladora, a compilação hierárquica, como um recurso ativado mediante consentimento. O objetivo da compilação em camadas é melhorar o desempenho. Uma das tarefas importantes executadas pelo compilador JIT é otimizar a execução de código. No entanto, para caminhos de código pouco usados, o compilador pode gastar mais tempo otimizando o código do que o runtime gasta executando código não otimizado. A compilação em camadas introduz dois estágios na compilação JIT:

  • Uma primeira camada, que gera código o mais rápido possível.

  • Uma segunda camada, que gera código otimizado para os métodos executados com frequência. A segunda camada de compilação é executada em paralelo para melhorar o desempenho.

Para saber mais sobre melhoria de desempenho que pode resultar da compilação em camadas, consulte Anúncio do .NET Core 2.2 Versão prévia 2.

Para obter informações sobre como optar pela compilação em camadas, consulte Melhorias do compilador Jit em Novidades no .NET Core 2.1.

Runtime

Injeção de código antes de executar o método Main

A partir do .NET Core 2.2, você pode usar um gancho de inicialização para injetar código antes da execução do método Main de um aplicativo. Ganchos de inicialização tornam possível para um host personalizar o comportamento de aplicativos após eles terem sido implantados, sem a necessidade de recompilar ou alterar o aplicativo.

Esperamos que os provedores de hospedagem definam a configuração e a política personalizadas, incluindo configurações que potencialmente influenciam o comportamento de carga do ponto de entrada principal, como o System.Runtime.Loader.AssemblyLoadContext comportamento. O gancho pode ser usado para configurar a injeção de rastreamento ou de telemetria, para configurar os retornos de chamada para tratamento ou para definir outro comportamento dependente do ambiente. O gancho é separado do ponto de entrada, para que o código do usuário não precise ser modificado.

Confira Gancho de inicialização do host para saber mais.

Confira também