web-dev-qa-db-ja.com

非同期コンソールアプリケーションは.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!");
        }
    }
}

これらは両方ともエラーで失敗します:

エラーCS5001:プログラムには、エントリポイントに適した静的な 'Main'メソッドが含まれていません

非同期コンソールアプリケーションは.NET Core RTMでサポートされていますか?

99
kimsagro

はい、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コア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:非同期メイン
  2. チャンピオン「非同期メイン」(C#7.1)
154
Evgeny Bobkin

Update:非同期メインはC#7.1でネイティブにサポートされています!上記のEvgenyの answer を参照してください。

私は後世のために以下の回避策を維持しますが、もはや必要ありません。 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

48
Nate Barbettini

非同期エントリポイントのサポートはしばらく前に削除されました。

Aspnet/announcements 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

10
Nick Acosta