Czy aplikacje konsoli asynchronicznej są obsługiwane w programie .NET Core?


113

W pewnym momencie CoreCLR obsługiwał asynchroniczne główne punkty wejścia. Zobacz http://blog.stephencleary.com/2015/03/async-console-apps-on-net-coreclr.html

Jednak oba poniższe programy nie działają w .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!");
        }
    }
}

lub

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!");
        }
    }
}

Oba kończą się niepowodzeniem z powodu błędu:

błąd CS5001: Program nie zawiera statycznej metody „Main” odpowiedniej dla punktu wejścia

Czy aplikacje konsoli asynchronicznej są obsługiwane w programie .NET Core RTM?



6
@svick faktycznie async Główne wsparcie zostało dodane w c # 7.1, docs.microsoft.com/en-us/dotnet/csharp/whats-new/ ... - W projekcie Visual Studio 2017 przejdź do właściwości projektu -> kompilacja -> zaawansowane , a następnie zmień wersję językową na 7.1 (lub nowszą)
alv

1
Pamiętaj, aby zmienić properties -> build -> advanced -> language versiontypy kompilacji Debuguj i wydaj, w przeciwnym razie projekt nie powiedzie się po opublikowaniu.
Mark

2
W moim projekcie „async Main” działa tylko wtedy, gdy korzystam z Task zamiast void. W przypadku nieważności otrzymałem błąd „CS5001”.
Felipe Deveza,

Odpowiedzi:


175

Tak, async Mainfunkcje są obsługiwane od .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

Obsługa async Mainfunkcji została wprowadzona w języku C # w wersji 7.1. Jednak ta funkcja nie jest dostępna po wyjęciu z pudełka. Aby skorzystać z tej funkcji, musisz jawnie określić C # wersję 7.1 w swoim .csprojpliku, dołączając

<LangVersion>latest</LangVersion>

lub przez

<LangVersion>7.1</LangVersion>

Na przykład dla projektu 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>

gdzie główną funkcję można przepisać w następujący sposób:

using System.Threading.Tasks;

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

Bibliografia:

  1. Seria C # 7, część 2: Async Main
  2. Mistrz „Async Main” (C # 7.1)

6
Możesz także ustawić wersję językową (teraz?) We właściwościach projektu; Kompilacja -> Zaawansowane -> Wersja językowa.
Nick

Domyślnie ta opcja ma wartość „Najnowsza wersja główna” i jest równa 7.0, a nie 7.1! Zmień to ręcznie.
Eugene Hoza

1
Pierwszy link referencyjny jest martwy; oto pamięć podręczna maszyny Wayback: web.archive.org/web/20190118084407/https://…
kristianp

1
Link jest martwy, ponieważ pracownicy firmy Microsoft najwyraźniej muszą
kristianp

50

Aktualizacja : Async main jest obsługiwany natywnie przez C # 7.1! Zobacz odpowiedź Evgeny powyżej.

Poniższe obejście zachowam dla potomności, ale nie jest już potrzebne. async mainjest o wiele prostsze.


Jak powiedział Nick, obsługa tego została usunięta. To jest moje preferowane obejście:

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()działa tak samo jak .Wait(blokowanie synchroniczne), ale jest preferowane, ponieważ usuwa wyjątki.

Istnieje propozycja dodania async Main()do przyszłej wersji C #: csharplang # 97


10

Wsparcie dla asynchronicznych punktów wejścia zostało usunięte jakiś czas temu.

Zobacz ten problem na github aspnet / Anncements.

Zdecydowaliśmy się pójść w kierunku ujednolicenia semantyki punktu wejścia z desktopowym CLR.

Przestarzały w RC1:

Wsparcie dla async / Task <> Main.

Wsparcie dla tworzenia instancji typu punktu wejścia (Program).

Metoda Main powinna być public static void Main lub public static int Main.

Obsługa wstrzykiwania zależności do konstruktora klasy Program i metody Main.

Zamiast tego użyj PlatformServices i CompilationServices.

Aby dostać się do IApplicationEnvironment, IRuntimeEnvironment, IAssemblyLoaderContainer, IAssemblyLoadContextAccessor, ILibraryManager, użyj obiektu statycznego Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default.

Aby dostać się do ILibraryExporter, ICompilerOptionsProvider używa statycznego obiektu Microsoft.Extensions.CompilationAbstractions.CompilationServices.Default.

Wsparcie dla CallContextServiceLocator. Zamiast tego użyj PlatformServices i CompilationServices.

Tak samo jak powyżej.

Zostałyby usunięte w RC2: # 106

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.