非同期ラムダの利用 - await async と併用したラムダ式の利用 - C#
非同期ラムダの利用とコードについて紹介します。
概要
ラムダ式を利用するとデリゲートをシンプルに記述することができます。(
参考)
一方でメソッドには従来から利用されてきた同期メソッドに加え、非同期メソッドがC# 5.0から利用できるようになりました。
非同期メソッドのデリゲートをラムダ式で表現することもできます。この記事では、ラムダ式で非同期メソッドのデリゲートを表現する方法を紹介します。
書式
以下の書式を利用します。
非同期ラムダを利用しない場合
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 AsyncLambdaExpressions
{
public partial class FormMain : Form
{
int value = 200;
public FormMain()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
await AsyncProc();
textBox1.Text += "value:"+Convert.ToString(value)+"\r\n";
}
private async Task AsyncProc()
{
await Task.Delay(1000);
value += 100;
}
}
}
解説
button1をクリックすると、await async を利用した非同期処理でAsyncProc()が呼び出されます。
AsyncProcではDelay処理により、処理が1秒間停止しますが、AsybncProc自体が非同期で呼び出されているため、Delay中でもUIはフリーズせずに操作できます。Delay後valueに100を加算し、AsybncProcを抜けます。
メインスレッドは、button1のClickでawait AsynProc()を呼び出した後は、以降の行は実行せず、非同期処理の戻りを待つため、valueに100が加算され、AsyncProc関数の処理を抜けた後で、テキストボックスにvalueの値を表示します。
async, awaitの動作の詳細については
こちらの記事を参照してください。
実行結果
プロジェクトを実行します。下図のウィンドウが表示されます。
[button1]をクリックします。初期値の200に100を加算した"300"がテキストボックスに表示されます。
[button1]をクリックするごとに、100加算された値がテキストボックスに表示されます。
非同期ラムダを利用する場合
先のプログラムをラムダ式を利用したコードに変更します。
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 AsyncLambdaExpressions
{
public partial class FormMain : Form
{
int value = 200;
public FormMain()
{
InitializeComponent();
button2.Click += async (sender, e) =>
{
await AsyncProc();
textBox1.Text += "value:" + Convert.ToString(value) + "\r\n";
};
}
private async Task AsyncProc()
{
await Task.Delay(1000);
value += 100;
}
}
}
解説
button2のClickイベントをフォームのコンストラクタ中で実装しています。
デリゲートとラムダ式の書き換えでも紹介している、デリゲートをラムダ式で記述する方式でbutton2のclickイベントを実装しています。
ただし、今回はasync, await を用いた非同期関数の実装のため、ラムダ式の先頭に async キーワードを記述します。
実行結果
プロジェクトを実行します。下図のウィンドウが表示されます。
[button1]をクリックします。初期値の200に100を加算した"300"がテキストボックスに表示されます。
[button1]をクリックするごとに、100加算された値がテキストボックスに表示されます。
非同期ラムダを利用する場合 (その2)
上記のコードでは、
AsyncProc()
メソッドをメソッドで実装していましたが、この処理を非同期ラムダ式を利用してインラインで記述するコードを紹介します。
UI
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 AsyncLambdaExpressions
{
public partial class FormMain : Form
{
int value = 200;
public FormMain()
{
InitializeComponent();
button3.Click += async (sender, e) =>
{
Func<Task> f = async () =>{
await Task.Delay(1000);
value += 100;
};
await f();
textBox1.Text += "value:" + Convert.ToString(value) + "\r\n";
};
}
}
}
解説
button3のClickイベントをフォームのコンストラクタ中で実装しています。
デリゲートをラムダ式で記述する方式でbutton2のclickイベントを実装しています。先のコードと同様に非同期メソッドになるため、ラムダ式の先頭に async キーワードを記述します。
また、メソッドの実装部分で、先のプログラムでは
AsyncProc()
メソッドを非同期で呼び出していましたが、今回はメソッドで記述せずにインラインで記述します。
インラインで非同期メソッドを記述する場合は、
Func<Task>' の型の変数を宣言します。宣言した変数への代入はラムダ式を利用します。
ラムダ式の右辺にメソッドで実行するコート度記述します。今回の処理は先のプログラムの処理と同様に value メンバ変数に100を加算する処理をします。
メソッドの呼び出しは先のコードと同様に
await` キーワードを記述して呼び出します。
実行結果
プロジェクトを実行します。下図のウィンドウが表示されます。
[button3]をクリックします。初期値の200に100を加算した"300"がテキストボックスに表示されます。
[button1]をクリックするごとに、100加算された値がテキストボックスに表示されます。先に紹介したコードと同じ動作になっていることが確認できます。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用