web-dev-qa-db-ja.com

IWebHost:Run()とRunAsync()の呼び出し

新しい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内で非同期メソッドを呼び出す方がはるかに簡単です。

したがって、IWebHostRunAsync()は、Run()メソッドの代わりにMain内で呼び出すことができます。このようなもの:

_public static async Task Main(string[] args)
{
    await BuildWebHost(args).RunAsync().ConfigureAwait(false);
}
_

ドキュメントによるとRunメソッド:

Webアプリケーションを実行し、ホストがシャットダウンするまで呼び出しスレッドをブロックします。

一方、RunAsyncメソッド:

Webアプリケーションを実行し、トークンがトリガーされたとき、またはシャットダウンがトリガーされたときにのみ完了するタスクを返します。

通常のRunAsyncメソッドの代わりにRunメソッドをいつ使用するべきか疑問に思っていましたか?これの実際的な意味は何ですか?エンドユーザーは違いに気付くでしょうか?

20
Ali Zahid

デフォルトの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内であり、その外ではありません)でセットアップ作業を行う可能性が高くなります。

12
poke

これの実際的な意味は何ですか?エンドユーザーは違いに気付くでしょうか?

RunTimeレベルの動作に違いはありません。

この機能はCLRコードの変更に対応していないため、async Mainメソッドは構文上の砂糖です。この設計により、言語の以前のバージョンとのバックエンド互換性が可能になります。詳細については、Roslyn GitリポジトリのAsync Mainを参照してください。
- C#7シリーズ、パート2:非同期メイン

1
idubnori