Are async console applications supported in .NET Core?

C#.Net.Net Core

C# Problem Overview


At some point in time the CoreCLR supported async main entry points. See http://blog.stephencleary.com/2015/03/async-console-apps-on-net-coreclr.html

However both the following programs are not working in .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!");
        }
    }
}

or

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

These both fail with the error:

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

Are async console applications supported in .NET Core RTM?

C# Solutions


Solution 1 - C#

Yes, the async Main functions are supported since .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

The support for the async Main functions is introduced in C# version 7.1. However, this functionality is not available out of the box. To make use of this feature you need explicitly specify the C# version 7.1 in your .csproj file, either by including

<LangVersion>latest</LangVersion>

or by

<LangVersion>7.1</LangVersion>

For example for the ASP.NET core 2.0 project:

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

where the Main function can be rewritten as following:

using System.Threading.Tasks;

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

References:

  1. C# 7 Series, Part 2: Async Main
  2. Champion "Async Main" (C# 7.1)

Solution 2 - C#

Update: Async main is supported natively by C# 7.1! See Evgeny's answer above.

I'll keep the below workaround for posterity, but it is no longer needed. async main is way simpler, use that if you can!


This is my preferred workaround in C# less than 7.1:

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() is the same as .Wait (blocking synchronously), but is preferred because it unwraps exceptions.

Solution 3 - C#

Support for async entry points was removed a while back.

See this issue on the aspnet/announcements github.

> 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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkimsagroView Question on Stackoverflow
Solution 1 - C#Evgeny BobkinView Answer on Stackoverflow
Solution 2 - C#Nate BarbettiniView Answer on Stackoverflow
Solution 3 - C#Nick AcostaView Answer on Stackoverflow