.NET Core 是否支持异步控制台应用程序?

Are async console applications supported in .NET Core?

在某个时间点,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!");
        }
    }
}

这些都因错误而失败:

error CS5001: Program does not contain a static 'Main' method suitable for an entry point

.NET Core RTM 是否支持异步控制台应用程序?

不久前删除了对异步入口点的支持。

参见 aspnet/announcements github 上的 this issue

We decided to move towards unification of entry point semantics with desktop CLR.

Obsolete in RC1:

Support for async/Task<> Main.

Support for instantiating of entry point type (Program).

The Main method should be public static void Main or public static int Main.

Support for injecting dependencies into the Program class's constructor and Main method.

Use PlatformServices and CompilationServices instead.

To get to IApplicationEnvironment, IRuntimeEnvironment, IAssemblyLoaderContainer, IAssemblyLoadContextAccessor, ILibraryManager use Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default static object.

To get to ILibraryExporter, ICompilerOptionsProvider use the Microsoft.Extensions.CompilationAbstractions.CompilationServices.Default static object.

Support for CallContextServiceLocator. Use PlatformServices and CompilationServices instead.

Same as above.

These would be removed in RC2: #106

更新:C# 7.1 原生支持 Async main!参见上面 Evgeny 的

我会为后代保留以下解决方法,但不再需要它。 async main 更简单,如果可以就使用它!


这是我首选的解决方法在低于 7.1 的 C# 中:

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 相同(同步阻塞),但 is preferred 因为它解包异常。

是的,自 .NET Core 2.0 起支持 async Main 函数。

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

在 C# 7.1 版中引入了对 async Main 函数的支持。但是,此功能不是开箱即用的。要使用此功能,您需要在 .csproj 文件中明确指定 C# 版本 7.1,方法是包含

<LangVersion>latest</LangVersion>

或通过

<LangVersion>7.1</LangVersion>

例如 ASP.NET 核心 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 Series, Part 2: Async Main
  2. Champion "Async Main" (C# 7.1)