Поддерживаются ли консольные асинхронные приложения в .NET Core?

113

В какой-то момент CoreCLR поддерживал основные точки входа async. См. Http://blog.stephencleary.com/2015/03/async-console-apps-on-net-coreclr.html

Однако обе следующие программы не работают в .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!");
        }
    }
}

или

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

Оба они терпят неудачу с ошибкой:

ошибка CS5001: Программа не содержит статического метода Main, подходящего для точки входа

Поддерживаются ли консольные асинхронные приложения в .NET Core RTM?

кимсагро
источник
6
@svick на самом деле async Основная поддержка была добавлена ​​в С # 7.1, docs.microsoft.com/en-us/dotnet/csharp/whats-new/… - В своем проекте Visual Studio 2017 перейдите в свойства проекта -> build -> advanced , затем измените вашу языковую версию на 7.1 (или выше)
alv
1
Не забудьте изменить properties -> build -> advanced -> language version типы сборки Debug AND Release, иначе проект не удастся опубликовать.
Марк
2
В моем проекте async Main работает только в том случае, если я использовал Task вместо void. С void я получил ошибку «CS5001».
Фелипе Девеза

Ответы:

176

Да, async Mainфункции поддерживаются с тех пор .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

Поддержка async Mainфункций представлена ​​в C # версии 7.1. Однако эта функция недоступна по умолчанию. Чтобы использовать эту функцию, вам необходимо явно указать C # версии 7.1 в вашем .csprojфайле, либо включив

<LangVersion>latest</LangVersion>

или по

<LangVersion>7.1</LangVersion>

Например, для проекта 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>

где функцию Main можно переписать следующим образом:

using System.Threading.Tasks;

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

Ссылки:

  1. Серия C # 7, часть 2: Async Main
  2. Чемпион "Async Main" (C # 7.1)
Евгений Бобкин
источник
6
Вы также можете установить языковую версию (сейчас?) В свойствах проекта; Сборка -> Дополнительно -> Языковая версия.
Ник
По умолчанию эта опция имеет значение «последняя основная версия» и равна 7.0, а не 7.1! Измените его вручную.
Eugene Hoza 05
1
Первая ссылка мертва; вот машинный кеш обратного пути: web.archive.org/web/20190118084407/https://…
kristianp
1
Ссылка мертва, потому что сотрудникам Microsoft, очевидно, необходимо вручную перенести свои блоги: social.technet.microsoft.com/Forums/en-US/…
kristianp
50

Обновление : Async main изначально поддерживается C # 7.1! См. Евгения Ответ выше.

Я сохраню описанный ниже обходной путь для потомков, но он больше не нужен. async mainпуть проще.


Как сказал Ник, поддержка этого была удалена. Это мой предпочтительный обходной путь:

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()то же самое, что .Wait(блокировка синхронно), но предпочтительнее так как разворачивает исключения.

Есть предложение добавить async Main()в будущую версию C #: csharplang # 97

Нейт Барбеттини
источник
10

Некоторое время назад поддержка асинхронных точек входа была удалена.

См. Эту проблему в aspnet / объявлениях github.

Мы решили двигаться в сторону унификации семантики точки входа с настольной CLR.

Устарело в RC1:

Поддержка async / Task <> Main.

Поддержка создания экземпляров типа точки входа (Программа).

Метод Main должен быть public static void Main или public static int Main.

Поддержка внедрения зависимостей в конструктор класса Program и метод Main.

Вместо этого используйте PlatformServices и CompilationServices.

Чтобы перейти к IApplicationEnvironment, IRuntimeEnvironment, IAssemblyLoaderContainer, IAssemblyLoadContextAccessor, ILibraryManager, используйте статический объект Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default.

Чтобы добраться до ILibraryExporter, ICompilerOptionsProvider использует статический объект Microsoft.Extensions.CompilationAbstractions.CompilationServices.Default.

Поддержка CallContextServiceLocator. Вместо этого используйте PlatformServices и CompilationServices.

То же, что и выше.

Они будут удалены в RC2: # 106

Ник Акоста
источник