Async Console Programs非同期コンソールプログラム

2324 ワード

コンソールプログラムを書いている場合は、最終的に非同期mainメソッドが必要になる可能性があります.
class Program
{
  static async void Main(string[] args)
  {
    ...
  }
}

残念なことに、それは役に立たない(実際、VS 11コンパイラは非同期Mainメソッドを拒否している).私のこのブログ「Async and Await非同期と待機」では、非同期メソッドが完了すると呼び出し元に戻ると述べています.これはUIアプリケーション(方法はUIイベントループのみに戻る)およびASP.NET(メソッドがスレッドから離れて戻っても要求は生きている[ライフサイクル内])では完璧に動作しますが、コンソールプログラムではうまく動作しません.Mainがオペレーティングシステムに戻ったので、あなたのプログラムは終了しました.
独自の互換性を提供することで、非同期コンテキストを変更することができます.AsyncContext(非同期コンテキスト)は、非同期のMainAsyncを有効にする汎用コンテキストです.
class Program
{
  static int Main(string[] args)
  {
    try
    {
      return AsyncContext.Run(() => MainAsync(args));
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return -1;
    }
  }

  static async Task<int> MainAsync(string[] args)
  {
    ...
  }
}

以下はよくある問題で、望園友たちは注意してください.
問:「.Wait()」を使用して非同期のMainメソッドからの非同期メソッドを待つには、AsyncContextを使用することをお勧めしますか?
答え:MainメソッドではAsyncContextを使用するかGetAwaiter()を使用する.GetResult().GetAwaiter().GetResult()は本質的にWait()と同じですが、AggregateExceptionに異常をカプセル化していません.
AsyncContextは、メインコンソールスレッドに実際の単一スレッドコンテキストをアセンブリします.GetAwaiter().GetResult()は、フリーコンテキストのデフォルトをコンソールアプリケーションに保持します.もし私が概念証明型のコードを書いていたら、最終的にASP.NETまたはUIアプリケーション(単一スレッドコンテキストを持つ)で終了し、私は通常AsyncContextを使用します.もし私が本当のコンソールアプリケーションを書いていたら、私は任意の方法を選ぶことができます.