Les applications de console asynchrone sont-elles prises en charge dans .NET Core?

113

À un moment donné, CoreCLR a pris en charge les principaux points d'entrée asynchrones. Voir http://blog.stephencleary.com/2015/03/async-console-apps-on-net-coreclr.html

Cependant, les deux programmes suivants ne fonctionnent pas dans .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!");
        }
    }
}

Ces deux échouent avec l'erreur:

erreur CS5001: le programme ne contient pas de méthode statique «principale» adaptée à un point d'entrée

Les applications de console asynchrone sont-elles prises en charge dans .NET Core RTM?

kimsagro
la source
6
@svick en fait async Le support principal a été ajouté dans c # 7.1, docs.microsoft.com/en-us/dotnet/csharp/whats-new/… - Dans votre projet Visual Studio 2017, accédez aux propriétés du projet -> build -> avancé , puis changez votre version linguistique en 7.1 (ou plus)
alv
1
N'oubliez pas de modifier les properties -> build -> advanced -> language versiontypes de build Debug AND Release, sinon le projet échouera lors de la publication.
Mark
2
Dans mon projet, «async Main» ne fonctionne que si j'ai utilisé Task au lieu de void. Avec void, j'ai reçu l'erreur «CS5001».
Felipe Deveza

Réponses:

175

Oui, les async Mainfonctions sont supportées depuis .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

La prise en charge des async Mainfonctions est introduite dans C # version 7.1. Cependant, cette fonctionnalité n'est pas disponible par défaut. Pour utiliser cette fonctionnalité, vous devez spécifier explicitement la version C # 7.1 dans votre .csprojfichier, soit en incluant

<LangVersion>latest</LangVersion>

ou par

<LangVersion>7.1</LangVersion>

Par exemple pour le projet 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>

où la fonction principale peut être réécrite comme suit:

using System.Threading.Tasks;

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

Références:

  1. Série C # 7, partie 2: Async Main
  2. Champion "Async Main" (C # 7.1)
Evgeny Bobkin
la source
6
Vous pouvez également définir la version linguistique (maintenant?) Dans les propriétés du projet; Build -> Advanced -> Language version.
Nick
Par défaut, cette option a la valeur "dernière version majeure" et est égale à 7.0, pas 7.1! Modifiez-le manuellement.
Eugene Hoza
1
Le premier lien de référence est mort; voici le cache de la machine de retour: web.archive.org/web/20190118084407/https
kristianp
1
Le lien est mort car les employés de Microsoft doivent apparemment migrer leurs blogs manuellement: social.technet.microsoft.com/Forums/en-US/…
kristianp
50

Mise à jour : Async main est supporté nativement par C # 7.1! Voir la réponse d'Evgeny ci-dessus.

Je vais garder la solution de contournement ci-dessous pour la postérité, mais elle n'est plus nécessaire. async mainest bien plus simple.


Comme Nick l'a dit, le support pour cela a été supprimé. C'est ma solution de contournement préférée:

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()est identique à .Wait(blocage synchrone), mais il est préférable car il déballe les exceptions.

Il existe une proposition d'ajout async Main()à une future version de C #: csharplang # 97

Nate Barbettini
la source
10

La prise en charge des points d'entrée asynchrones a été supprimée il y a quelque temps.

Consultez ce problème sur le github aspnet / annonces.

Nous avons décidé d'aller vers l'unification de la sémantique des points d'entrée avec le CLR de bureau.

Obsolète dans RC1:

Prise en charge de async / Task <> Main.

Prise en charge de l'instanciation du type de point d'entrée (programme).

La méthode Main doit être public static void Main ou public static int Main.

Prise en charge de l'injection de dépendances dans le constructeur de la classe Program et la méthode Main.

Utilisez plutôt PlatformServices et CompilationServices.

Pour accéder à IApplicationEnvironment, IRuntimeEnvironment, IAssemblyLoaderContainer, IAssemblyLoadContextAccessor, ILibraryManager utilise l'objet statique Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default.

Pour accéder à ILibraryExporter, ICompilerOptionsProvider utilise l'objet statique Microsoft.Extensions.CompilationAbstractions.CompilationServices.Default.

Prise en charge de CallContextServiceLocator. Utilisez plutôt PlatformServices et CompilationServices.

Comme ci-dessus.

Ceux-ci seraient supprimés dans RC2: # 106

Nick Acosta
la source