¿Las aplicaciones de consola asíncronas son compatibles con .NET Core?

113

En algún momento, CoreCLR admitió puntos de entrada principales asíncronos. Ver http://blog.stephencleary.com/2015/03/async-console-apps-on-net-coreclr.html

Sin embargo, los dos programas siguientes no funcionan en .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!");
        }
    }
}

o

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 fallan con el error:

error CS5001: el programa no contiene un método 'principal' estático adecuado para un punto de entrada

¿Las aplicaciones de consola asíncronas son compatibles con .NET Core RTM?

kimsagro
fuente
6
@svick realmente async Se ha agregado soporte principal en c # 7.1, docs.microsoft.com/en-us/dotnet/csharp/whats-new/… - En su proyecto de visual studio 2017, vaya a propiedades del proyecto -> compilación -> avanzado , luego cambie su versión de idioma a 7.1 (o superior)
alv
1
Recuerde cambiar los properties -> build -> advanced -> language versiontipos de compilación Debug AND Release, de lo contrario, el proyecto fallará en Publish.
Marcos
2
En mi proyecto, 'async Main' solo funciona si utilicé Task en lugar de void. Con void recibí el error 'CS5001'.
Felipe Deveza

Respuestas:

175

Sí, las async Mainfunciones son compatibles desde .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

El soporte para las async Mainfunciones se introduce en la versión 7.1 de C #. Sin embargo, esta funcionalidad no está disponible de forma inmediata. Para hacer uso de esta función, debe especificar explícitamente la versión 7.1 de C # en su .csprojarchivo, ya sea incluyendo

<LangVersion>latest</LangVersion>

o por

<LangVersion>7.1</LangVersion>

Por ejemplo, para el proyecto 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>

donde la función principal se puede reescribir de la siguiente manera:

using System.Threading.Tasks;

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

Referencias:

  1. Serie C # 7, parte 2: Async Main
  2. Campeón "Async Main" (C # 7.1)
Evgeny Bobkin
fuente
6
También puede establecer la versión de idioma (¿ahora?) En las propiedades del proyecto; Compilación -> Avanzado -> Versión de idioma.
Nick
De forma predeterminada, esta opción tiene el valor "última versión principal" y es igual a 7.0, no a 7.1. Cámbielo manualmente.
Eugene Hoza
1
El primer enlace de referencia está muerto; aquí está el caché de la máquina wayback: web.archive.org/web/20190118084407/https://…
kristianp
1
El enlace está muerto porque los empleados de Microsoft necesitan migrar sus blogs manualmente aparentemente: social.technet.microsoft.com/Forums/en-US/…
kristianp
50

Actualización : ¡Async main es compatible de forma nativa con C # 7.1! Vea la respuesta de Evgeny arriba.

Conservaré la siguiente solución alternativa para la posteridad, pero ya no es necesaria. async maines mucho más sencillo.


Como dijo Nick, se eliminó el apoyo a esto. Esta es mi solución 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()es lo mismo que .Wait(bloquear sincrónicamente), pero se prefiere porque desenvuelve las excepciones.

Hay una propuesta para agregar async Main()a una versión futura de C #: csharplang # 97

Nate Barbettini
fuente
10

El soporte para puntos de entrada asíncronos se eliminó hace un tiempo.

Vea este problema en el github de aspnet / anuncios.

Decidimos avanzar hacia la unificación de la semántica del punto de entrada con CLR de escritorio.

Obsoleto en RC1:

Soporte para async / Task <> Main.

Soporte para instanciar el tipo de punto de entrada (Programa).

El método Main debe ser public static void Main o public static int Main.

Soporte para inyectar dependencias en el constructor de la clase Program y en el método Main.

En su lugar, utilice PlatformServices y CompilationServices.

Para llegar a IApplicationEnvironment, IRuntimeEnvironment, IAssemblyLoaderContainer, IAssemblyLoadContextAccessor, ILibraryManager utilice el objeto estático Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default.

Para llegar a ILibraryExporter, ICompilerOptionsProvider usa el objeto estático Microsoft.Extensions.CompilationAbstractions.CompilationServices.Default.

Soporte para CallContextServiceLocator. En su lugar, utilice PlatformServices y CompilationServices.

Lo mismo que arriba.

Estos se eliminarían en RC2: # 106

Nick Acosta
fuente