Le applicazioni console asincrone sono supportate in .NET Core?


113

Ad un certo punto nel tempo CoreCLR ha supportato i punti di ingresso principali asincroni. Vedi http://blog.stephencleary.com/2015/03/async-console-apps-on-net-coreclr.html

Tuttavia, entrambi i programmi seguenti non funzionano in .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!");
        }
    }
}

Entrambi falliscono con l'errore:

errore CS5001: il programma non contiene un metodo "Main" statico adatto per un punto di ingresso

Le applicazioni console asincrone sono supportate in .NET Core RTM?



6
@svick effettivamente asincrono Il supporto principale è stato aggiunto in c # 7.1, docs.microsoft.com/en-us/dotnet/csharp/whats-new/… - Nel tuo progetto Visual Studio 2017, vai alle proprietà del progetto -> build -> advanced , quindi modifica la versione della lingua in 7.1 (o successiva)
alv

1
Ricorda di cambiare properties -> build -> advanced -> language versionper i tipi di build Debug AND Release, altrimenti il ​​progetto fallirà in Publish.
Marco

2
Nel mio progetto, "async Main" funziona solo se ho usato Task invece di void. Con void ho ricevuto l'errore "CS5001".
Felipe Deveza

Risposte:


175

Sì, le async Mainfunzioni sono supportate da allora .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

Il supporto per le async Mainfunzioni è stato introdotto in C # versione 7.1. Tuttavia, questa funzionalità non è disponibile immediatamente. Per utilizzare questa funzionalità è necessario specificare esplicitamente la versione 7.1 di C # nel .csprojfile, includendo

<LangVersion>latest</LangVersion>

o da

<LangVersion>7.1</LangVersion>

Ad esempio per il progetto 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>

dove la funzione Main può essere riscritta come segue:

using System.Threading.Tasks;

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

Riferimenti:

  1. Serie C # 7, parte 2: Async Main
  2. Champion "Async Main" (C # 7.1)

6
Puoi anche impostare la versione della lingua (ora?) Nelle proprietà del progetto; Build -> Advanced -> Language version.
Nick

Per impostazione predefinita, questa opzione ha il valore "ultima versione principale" ed è uguale a 7.0, non 7.1! Modificalo manualmente.
Eugene Hoza

1
Il primo collegamento di riferimento è morto; ecco la cache della macchina wayback: web.archive.org/web/20190118084407/https://…
kristianp

1
Il collegamento è morto perché i dipendenti Microsoft devono migrare i loro blog manualmente apparentemente: social.technet.microsoft.com/Forums/en-US/…
kristianp

50

Aggiornamento : Async main è supportato nativamente da C # 7.1! Vedi la risposta di Evgeny sopra.

Terrò la soluzione alternativa di seguito per i posteri, ma non è più necessaria. async mainè molto più semplice.


Come ha detto Nick, il supporto per questo è stato rimosso. Questa è la mia soluzione alternativa preferita:

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()è uguale a .Wait(blocco in modo sincrono), ma è preferito perché elimina le eccezioni.

È disponibile una proposta per l'aggiunta async Main()a una versione futura di C #: csharplang # 97


10

Il supporto per i punti di ingresso asincroni è stato rimosso qualche tempo fa.

Vedere questo problema su github aspnet / annunci.

Abbiamo deciso di passare all'unificazione della semantica del punto di ingresso con CLR desktop.

Obsoleto in RC1:

Supporto per async / Task <> Main.

Supporto per la creazione di istanze del tipo di punto di ingresso (programma).

Il metodo Main dovrebbe essere public static void Main o public static int Main.

Supporto per l'inserimento di dipendenze nel costruttore della classe Program e nel metodo Main.

Utilizza invece PlatformServices e CompilationServices.

Per arrivare a IApplicationEnvironment, IRuntimeEnvironment, IAssemblyLoaderContainer, IAssemblyLoadContextAccessor, ILibraryManager utilizzare l'oggetto statico Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default.

Per accedere a ILibraryExporter, ICompilerOptionsProvider utilizza l'oggetto statico Microsoft.Extensions.CompilationAbstractions.CompilationServices.Default.

Supporto per CallContextServiceLocator. Utilizza invece PlatformServices e CompilationServices.

Come sopra.

Questi sarebbero stati rimossi in RC2: # 106

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.