[C#] await async を用いたシンプルな非同期メソッドの作成と利用
このページのタグ:[C#] [非同期メソッド]
C#5.0 で導入された、awaitとasyncを利用してシンプルな非同期メソッドを作成して利用します。

サンプルプログラム

UI

以下のUIを作成します。

コード

以下のコードを記述します。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SimpleAsync
{
  public partial class FormMain : Form
  {
    public FormMain()
    {
      InitializeComponent();
    }

    private async void button1_Click(object sender, EventArgs e)
    {
      int result = await ComplexAsyncTask();
      textBox1.Text += Convert.ToString(result);
    }

    private async void button2_Click(object sender, EventArgs e)
    {
      int result = await ComplexAsyncTask2();
      textBox1.Text += Convert.ToString(result);
    }

    public async Task<int> ComplexAsyncTask()
    {
      Func<int> asyncJob = () =>
      {
        //時間のかかる処理
        int i = 0;
        for (i = 0; i < 1000000000; i++) {
        }
        return i;
      };

      int ret1 = await Task.Run(asyncJob);
      int ret2 = await Task.Run(asyncJob);
      return ret1 + ret2;
    }

    public async Task<int> ComplexAsyncTask2()
    {
      Func<int> asyncJob = Proc;
      int ret1 = await Task.Run(asyncJob);
      int ret2 = await Task.Run(asyncJob);
      return ret1 + ret2;
    }

    public int Proc()
    {
      //時間のかかる処理
      int i = 0;
      for (i = 0; i < 1000000000; i++) {
      }
      return i;
    }
  }
}

解説

ComplexAsyncTask()メソッドは、タスクの処理関数をラムダ式で記述しています。ComplexAsyncTask2()メソッドはタスクの処理は別メソッドになっており、代入によりデリゲートを作成しています。処理内容は同じです。
ポイントの一つ目は"button1_Click","button2_Click"のメソッドにasync修飾子を記述し、非同期メソッドにします。
(非同期メソッドという名称ですが、実行が非同期になるわけではありません。await でのメソッド呼び出しを待機する制御フローが組み込まれるだけです。)
Clickイベント内の

int result = await ComplexAsyncTask();
を実行することで、非同期のメソッド"ComplexAsyncTask()"を呼び出します。メソッド名の手前に await 演算子があるため、"ComplexAsyncTask()"メソッドの実行が完了するまで、以降の処理は実行されませんが、スレッドがブロックされることもありません。await以降の処理が、"ComplexAsyncTask()"メソッドの終了後に実行されるよう予約されます。
"ComplexAsyncTask()"メソッドの実行が完了すると、メソッドの戻り値がresultに代入されます。本来、"ComplexAsyncTask()"の戻り値はTask<int>ですが、await演算子が指定されている場合は、戻り値(int)の返却となります。

補足

awaitの後に指定できる型は"Awaitable"な型に限ります。現状では、Taskクラス, Task<TResult>クラスに限られます。

実行結果

プロジェクトを実行します。下図のフォームが表示されます。


[button1]または[button2]をクリックします。しばらく時間が経過した後計算結果がテキストボックスに表示されます。
非同期で実行されるため、ボタンを押してから計算結果がテキストボックスに表示されるまでの間でもUIはフリーズしません。


登録日 :2014-11-20    最終更新日 :2015-03-08
このページのタグ:[C#] [非同期メソッド]
Japanese
プライバシー    iPentecについて
iPentec all rights reserverd. (ISDC)