Чи підтримуються програми консолі async в .NET Core?


113

У якийсь момент CoreCLR підтримував асинхронізацію основних точок входу. Дивіться 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: Програма не містить статичного методу "Основний", придатного для точки входу

Чи підтримуються програми консолі async у .NET Core RTM?



6
@svick фактично async Основна підтримка додана в c # 7.1, docs.microsoft.com/en-us/dotnet/csharp/whats-new/… - У проекті візуальної студії 2017 перейдіть до властивостей проекту -> build -> Advanced , потім змініть мовну версію на 7.1 (або вище)
alv

1
Не забудьте змінити properties -> build -> advanced -> language versionтипи збірки налагодження та випуску, інакше проект не вийде з Publish.
Марк

2
У моєму проекті "async Main" працює лише в тому випадку, якщо я використовував Task замість пустоти. З недійсним я отримав помилку "CS5001".
Феліпе Deveza

Відповіді:


175

Так, 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функцій введена у версії 7.1 C #. Однак ця функція недоступна у вікні. Щоб скористатися цією функцією, вам потрібно чітко вказати у .csprojфайлі C # версії 7.1 , включивши їх

<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>

де головну функцію можна переписати наступним чином:

using System.Threading.Tasks;

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

Список літератури:

  1. Серія C # 7, частина 2: Основна асинхроніка
  2. Чемпіон "Async Main" (C # 7.1)

6
Ви також можете встановити мовну версію (зараз?) У властивостях проекту; Збірка -> Додатково -> Мовна версія.
Нік

За замовчуванням ця опція має значення "остання основна версія" і дорівнює 7,0, а не 7,1! Змініть її вручну.
Євген

1
Перше посилання посилання мертве; ось зворотний кеш-пам'ять машини: web.archive.org/web/20190118084407/https://…
kristianp

1
Посилання є мертвим, оскільки працівники Microsoft повинні мігрувати свої блоги вручну, мабуть: social.technet.microsoft.com/Forums/en-US/…
kristianp

50

Оновлення : Основна функція Async підтримується на 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

Підтримка вхідних точок асинхронізації була видалена на деякий час назад.

Дивіться цю проблему на веб-сайті github.

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

Застарілий у RC1:

Підтримка асинхронізації / завдання <> Головна.

Підтримка ідентифікації типу вхідної точки (Програма).

Метод Main повинен бути публічним статичним недійсним 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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.