新しいASP.NET Core 2.0プロジェクトが作成されると、Main
クラスのボイラープレートProgram
メソッドは次のようになります。
_public static void Main(string[] args)
{
BuildWebHost(args).Run(); // BuildWebHost returns an IWebHost
}
_
ただし、C#7.1以降、Main
メソッドは、Task
ではなくvoid
を返す非同期メソッドになる場合があります。つまり、Main
内で非同期メソッドを呼び出す方がはるかに簡単です。
したがって、IWebHost
のRunAsync()
は、Run()
メソッドの代わりにMain
内で呼び出すことができます。このようなもの:
_public static async Task Main(string[] args)
{
await BuildWebHost(args).RunAsync().ConfigureAwait(false);
}
_
ドキュメントによると 、Run
メソッド:
Webアプリケーションを実行し、ホストがシャットダウンするまで呼び出しスレッドをブロックします。
一方、RunAsync
メソッド:
Webアプリケーションを実行し、トークンがトリガーされたとき、またはシャットダウンがトリガーされたときにのみ完了するタスクを返します。
通常のRunAsync
メソッドの代わりにRun
メソッドをいつ使用するべきか疑問に思っていましたか?これの実際的な意味は何ですか?エンドユーザーは違いに気付くでしょうか?
デフォルトのASP.NET Coreテンプレートには、次のMain
メソッドが含まれています。
_public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
_
そのRun
メソッドには _WebHostExtensions.Run
_拡張メソッド があります これはこのように実装されています :
_public static void Run(this IWebHost Host)
{
Host.RunAsync().GetAwaiter().GetResult();
}
_
したがって、これは実際には _WebHostExtensions.RunAsync
_ を呼び出し、ブロックするだけです。
それでは、C#7.1の非同期Main
メソッド 指定あり を見てみましょう。
[これらのタスクベースのメソッド]の1つがエントリポイントとして識別されると、コンパイラは、これらのコード化されたメソッドの1つを呼び出す実際のエントリポイントメソッドを合成します。
static Task Main()
を指定すると、コンパイラはprivate static void $GeneratedMain() => Main().GetAwaiter().GetResult();
と同等の内容を出力します。static Task Main(string[])
を指定すると、コンパイラはprivate static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();
と同等の内容を出力します。
したがって、基本的には、次のような非同期のMain
メソッドがあります。
_public static async Task Main(string[] args)
{
await BuildWebHost(args).RunAsync();
}
_
コンパイラーは以下も発行します。
_private static void $GeneratedMain(string[] args)
{
Main(args).GetAwaiter().GetResult();
}
_
そして、返されたタスクで何が起こるかをよく見ると、これは_WebHostExtensions.Run
_メソッドが行うこととほとんど同じです。
これはどういう意味ですか?これらのソリューションのいずれかを使用でき、効果は同じになります。非同期タスクが解決されるまで、アプリケーションは適切にブロックされます。ソリューション間に実際的な違いはありません。非同期メインメソッドを使用することで得られる真のメリットは、Main
メソッドで他の非同期処理を行う場合に限られます。これは非常にまれなケースですが、Webアプリケーションの場合、ASP.NET Coreアプリケーションのライフサイクル内(つまり、Startup
内であり、その外ではありません)でセットアップ作業を行う可能性が高くなります。
これの実際的な意味は何ですか?エンドユーザーは違いに気付くでしょうか?
RunTimeレベルの動作に違いはありません。
この機能はCLRコードの変更に対応していないため、async Mainメソッドは構文上の砂糖です。この設計により、言語の以前のバージョンとのバックエンド互換性が可能になります。詳細については、Roslyn GitリポジトリのAsync Mainを参照してください。
- C#7シリーズ、パート2:非同期メイン