連載:C# 5.0&VB 11.0新機能「async/await非同期メソッド」入門

第2回 非同期メソッドの構文

鈴木 孝明
2012/09/25
Page1 Page2 Page3

任意の記述場所

 async修飾子やawait演算子を利用できる箇所は、List 1に示したような通常のメソッドだけにとどまらない。Table 1に示すように、「メソッド」や「式」として成立する箇所であればどこでも適用可能だ。

キーワード 適用可能箇所
async修飾子 通常のメソッド、ラムダ式、匿名メソッド
await演算子 式が書ける場所ならどこでも
Table 1: 非同期メソッドの適用可能箇所

 例えばList 3のように、非同期処理をそこかしこに書くことができる。

DoSomething(async () =>
{
  while (await CanExecuteAsync())
    await Task.Run(() => Thread.Sleep(3000));
});
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)

  DoSomething(
    Async Function()
      While (Await CanExecuteAsync())
        Await Task.Run(
          Function()
            Thread.Sleep(3000)
          End Function)
      End While
    End Function)

End Sub
List 3: 非同期メソッドのラムダ式への適用例(上:C#、下:VB)

 ただし、コンソール・アプリケーションやWindowsフォーム・アプリケーションなどで目にする「アプリケーションのエントリ・ポイント」や「インスタンスのコンストラクタ」には適用できないので注意が必要だ。また、finally句の中にawait演算子を記述することもできないので注意が必要だ。

戻り値

 ここまで特に意識してこなかったが、非同期メソッドにも戻り値は必要だ。戻り値にはvoid型/Task型/Task<T>型のいずれかを設定できる。戻り値をどのように選択すればよいのか、それぞれ確認していこう。

void型

 通常のメソッド同様、非同期メソッドでもreturn文を書かない場合は戻り値に“void”(Visual Basicでは“Sub”ステートメント)を指定できる。戻り値にvoidを指定するケースは、呼び出し元が非同期メソッドの完了を待機する必要がない場合だ。例えばGUIアプリケーションのイベント・ハンドラに適用する場合が挙げられる。List 1(以下に再掲)はその代表的な例といえるだろう。

private async void Button_Click(object sender, RoutedEventArgs e)
{
  this.button.IsEnabled = false;
  await HeavyWork();  // 何か重たい処理
  this.button.IsEnabled = true;
}
Private Async Sub Button_Click(sender As Object, e As RoutedEventArgs)

  Me.button.IsEnabled = False
  Await HeavyWork()  ' 何か重たい処理
  Me.button.IsEnabled = True

End Sub
List 1(再掲): 非同期メソッドの例(上:C#、下:VB)

Task型

 戻り値としてreturn文を書かない場合は、前述のvoid型だけでなくTask型も指定可能だ。List 4に簡単な例を示す。

static void Main()
{
  var task = DoSomethingAsync();
  // この間、何か別の処理をしたりするとよい
  task.Wait();
  Console.ReadKey();
}

static async Task DoSomethingAsync()
{
  await Task.Run(() => Thread.Sleep(3000));
}
Shared Sub Main()

  Dim task = DoSomethingAsync()
  ' この間、何か別の処理をしたりするとよい
  task.Wait()
  Console.ReadKey()

End Sub

Shared Async Function DoSomethingAsync() As Task

  Await Task.Run(
    Sub()
      Thread.Sleep(3000)
    End Sub)

End Function
List 4: 非同期メソッドの完了を待機(上:C#、下:VB)

 このように、呼び出し元で非同期メソッドの完了を待機したい場合に利用する。void型とTask型のどちらを選択するかは、

  • 「イベント・ハンドラかどうか」→ void型
  • 「待機したいかどうか」→ Task型

を指標にするとよいだろう。

Task<T>型

 非同期処理の結果を受け取りたい場合は、戻り値にTask<T>型を指定する。List 5にその例を示す。

static void Main()
{
  var task = CalculateSphereVolumeAsync(1);
  // この間、何か別の処理をしたりするとよい
  Console.WriteLine(task.Result);
  Console.ReadKey();
}

static async Task<double> CalculateSphereVolumeAsync(double radius)
{
  var π  = await Task.Run(() =>
  {
    Thread.Sleep(3000);
    return Math.PI;  // 級数展開などで円周率を計算したとする
  });
  return 4 * π  * Math.Pow(radius, 3) / 3;  // 球の体積
}
Shared Sub Main()

  Dim task = CalculateSphereVolumeAsync(1)
  ' この間、何か別の処理をしたりするとよい
  Console.WriteLine(task.Result)
  Console.ReadKey()

End Sub

Shared Async Function CalculateSphereVolumeAsync(radius As Double) As Task(Of Double)

  Dim π  = Await Task.Run(
    Function()
      Thread.Sleep(3000)
      Return Math.PI  ' 級数展開などで円周率を計算したとする
    End Function)
  Return 4 * π  * Math.Pow(radius, 3) / 3  ' 球の体積

End Function
List 5: 非同期メソッドから戻り値を取得(上:C#、下:VB)

 戻り値はTask<T>型だが、returnしているのはT型の値であることに注意してほしい。この変換はコンパイラが自動的に行ってくれる。かなり違和感があるかもしれないが、「いつもどおり、結果を返せばよい」とだけ覚えて飲み込んでいただきたい。

 次のページでは、例外処理などについて説明する。

 

 INDEX
  連載:C# 5.0&VB 11.0新機能「async/await非同期メソッド」入門
  第2回 非同期メソッドの構文
    1.非同期メソッドのキーワード/非同期メソッドの動き
  2.任意の記述場所/戻り値
    3.例外処理/UIスレッドに制御を戻すかどうかをカスタマイズする

 

インデックス・ページヘ  「連載:C# 5.0&VB 11.0新機能「async/await非同期メソッド」入門」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH