web-dev-qa-db-fra.com

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

À 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 'Main' adaptée à un point d'entrée

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

103
kimsagro

Oui, les fonctions async Main sont prises en charge 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 fonctions async Main est introduite dans la version 7.1 de C #. Cependant, cette fonctionnalité n'est pas disponible prête à l'emploi. Pour utiliser cette fonctionnalité, vous devez spécifier explicitement la version 7.1 de C # dans votre fichier .csproj, 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: Principal asynchrone
  2. Champion "Main Async" (C # 7.1)
159
Evgeny Bobkin

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 ce n'est plus nécessaire. async main est beaucoup plus simple.


Comme Nick l'a dit, le soutien à cela a été supprimé. Ceci est ma solution 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 est préféré car il annule les exceptions.

Il existe une proposition pour ajouter async Main() à une future version de C #: csharplang # 97

48
Nate Barbettini

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

Voir ce numéro sur le github aspnet/faire-part.

Nous avons décidé de progresser 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 et la méthode Main de la classe Program.

Utilisez plutôt PlatformServices et CompilationServices.

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

Pour se rendre à 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

10
Nick Acosta