Os aplicativos de console assíncronos são compatíveis com o .NET Core?

113

Em algum momento, o CoreCLR suportou pontos de entrada principais assíncronos. Consulte http://blog.stephencleary.com/2015/03/async-console-apps-on-net-coreclr.html

No entanto, os dois programas a seguir não estão funcionando no .NET Core RTM

using System;
using System.Threading.Tasks;

namespace ConsoleApplication
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            await Task.Delay(1000);
            Console.WriteLine("Hello World!");
        }
    }
}

ou

using System;
using System.Threading.Tasks;

namespace ConsoleApplication
{
    public class Program
    {
        public async Task Main(string[] args)
        {
            await Task.Delay(1000);
            Console.WriteLine("Hello World!");
        }
    }
}

Ambos falham com o erro:

erro CS5001: O programa não contém um método estático 'Principal' adequado para um ponto de entrada

Os aplicativos de console assíncronos são compatíveis com .NET Core RTM?

kimsagro
fonte
6
@svick na verdade async O suporte principal foi adicionado em c # 7.1, docs.microsoft.com/en-us/dotnet/csharp/whats-new/… - Em seu projeto do Visual Studio 2017, vá para propriedades do projeto -> construir -> avançado e, em seguida, altere a versão do seu idioma para 7.1 (ou superior)
alv
1
Lembre-se de alterar os properties -> build -> advanced -> language versiontipos de compilação Depurar E Liberar, caso contrário, o projeto falhará na Publicação.
Marcos
2
No meu projeto, 'async Main' só funciona se eu usar o Task em vez do void. Com void, recebi o erro 'CS5001'.
Felipe Deveza

Respostas:

175

Sim, as async Mainfunções são suportadas desde então .NET Core 2.0.

dotnet --info
.NET Command Line Tools (2.0.0)

Product Information:
 Version:            2.0.0
 Commit SHA-1 hash:  cdcd1928c9

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  16.04
 OS Platform: Linux
 RID:         ubuntu.16.04-x64
 Base Path:   /usr/share/dotnet/sdk/2.0.0/

Microsoft .NET Core Shared Framework Host

  Version  : 2.0.0
  Build    : e8b8861ac7faf042c87a5c2f9f2d04c98b69f28d

O suporte para as async Mainfunções é apresentado no C # versão 7.1. No entanto, essa funcionalidade não está disponível fora da caixa. Para usar este recurso, você precisa especificar explicitamente o C # versão 7.1 em seu .csprojarquivo, incluindo

<LangVersion>latest</LangVersion>

ou pela

<LangVersion>7.1</LangVersion>

Por exemplo, para o projeto ASP.NET core 2.0:

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <LangVersion>latest</LangVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
  </ItemGroup>
  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
    <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
    <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
  </ItemGroup>
</Project>

onde a função principal pode ser reescrita da seguinte forma:

using System.Threading.Tasks;

...
public static async Task Main(string[] args)
{
   await BuildWebHost(args).RunAsync();
}
...

Referências:

  1. Série C # 7, Parte 2: Assíncrono Principal
  2. Campeão "Async Main" (C # 7.1)
Evgeny Bobkin
fonte
6
Você também pode definir a versão do idioma (agora?) Nas propriedades do projeto; Construir -> Avançado -> Versão do idioma.
Nick
Por padrão, esta opção tem o valor "versão principal mais recente" e é igual a 7.0, não 7.1! Altere-o manualmente.
Eugene Hoza
1
O primeiro link de referência está morto; aqui está o cache de máquina de retorno
kristianp
1
O link está morto porque os funcionários da Microsoft precisam migrar seus blogs manualmente, aparentemente: social.technet.microsoft.com/Forums/en-US/…
kristianp
50

Atualização : Async main é suportado nativamente pelo C # 7.1! Veja a resposta de Evgeny acima.

Vou manter a solução alternativa abaixo para a posteridade, mas ela não é mais necessária. async mainé muito mais simples.


Como Nick disse, o suporte para isso foi removido. Esta é minha solução alternativa preferida:

using System;
using System.Threading.Tasks;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            MainAsync(args).GetAwaiter().GetResult();

            Console.ReadKey();
        }

        public static async Task MainAsync(string[] args)
        {
            await Task.Delay(1000);
            Console.WriteLine("Hello World!");
        }
    }
}

GetAwaiter().GetResult()é o mesmo que .Wait(bloquear de forma síncrona), mas é preferível porque desvenda as exceções.

Há uma proposta para adicionar async Main()a uma versão futura do C #: csharplang # 97

Nate Barbettini
fonte
10

O suporte para pontos de entrada assíncronos foi removido há um tempo.

Veja este problema no github aspnet / announcements.

Decidimos avançar para a unificação da semântica do ponto de entrada com o CLR de desktop.

Obsoleto em RC1:

Suporte para assíncrono / Tarefa <> Principal.

Suporte para instanciar o tipo de ponto de entrada (Programa).

O método Main deve ser public static void Main ou public static int Main.

Suporte para injetar dependências no construtor da classe Program e no método Main.

Em vez disso, use PlatformServices e CompilationServices.

Para obter o IApplicationEnvironment, IRuntimeEnvironment, IAssemblyLoaderContainer, IAssemblyLoadContextAccessor, ILibraryManager, use o objeto estático Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default.

Para chegar a ILibraryExporter, ICompilerOptionsProvider use o objeto estático Microsoft.Extensions.CompilationAbstractions.CompilationServices.Default.

Suporte para CallContextServiceLocator. Em vez disso, use PlatformServices e CompilationServices.

O mesmo que acima.

Eles seriam removidos em RC2: # 106

Nick Acosta
fonte