asyncとawaitを使って非同期処理を試してみる |
以前のブログ記事「【C#】非同期処理完了を通知する方法」で
Taskクラスを使った非同期処理を紹介しました。
.NET Framework4.5以降では演算子asyncとawaitが追加されました。
「もっと簡単に非同期処理が行えるようになったらしい」と話に聞いていたのですが
なかなか実践するタイミングがありませんでした。
やっと技術検証できましたのでその結果を記事にしてみます。
今回は「WCFとの通信を非同期処理」を例にして
前回の方法と「async・await」での実装方法を紹介します。
システム構成
WCFとWindowsFormsのサーバ・クライアントです。
検証環境
下記の環境を使用しています。
クライアント用(WindowsForms)
・VisualStudio Express 2013 for WindowsDesktop
WCF用
・VisualStudio Express 2013 for Web
サーバ側(WCF)の実装
1.プロジェクトテンプレートから「WCFサービスアプリケーション」を選んで
プロジェクトを新規作成してください。
2.サンプルのWCFメソッドをちょっと修正します。
(太文字が修正点です)
~省略~
namespace WcfServiceSample
{
// メモ: [リファクター] メニューの [名前の変更] コマンドを使用すると、コード、svc、および config ファイルで同時にクラス名 "Service1" を変更できます。
// 注意: このサービスをテストするために WCF テスト クライアントを起動するには、ソリューション エクスプローラーで Service1.svc または Service1.svc.cs を選択し、デバッグを開始してください。
public class Service1 : IService1
{
public string GetData(int value)
{
System.Threading.Thread.Sleep(3000);
return string.Format("You entered: {0}", value);
}
~省略~
}
}
クライアント側(WindowsForms)の基本実装
1.プロジェクトテンプレートから「Windowsフォームアプリケーション」を選んで
プロジェクトを新規作成してください。
※.NET Framework4.5で動作することを確認してください。
2.デザイナーでラベルを1つ、ボタンを3つ追加してください。
3.「サービス参照の追加」を行い、WCFメソッドを利用できるようにします。
4.ボタンクリックイベントで「タイトルに現在日時を表示する」処理を実装します。
非同期処理であることを確認するためのボタンです。
(同期処理である場合はボタンをクリックしても反応しない)
/// <summary>
/// タイトルを現在時間に設定する
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
this.Text = DateTime.Now.ToString();
}
クライアント側(WindowsForms)の非同期処理を実装
やっと非同期処理の比較が出来るようになりました。
下記の2つはどちらも
「ランダムな数値をパラメータにWCFメソッドをコール。戻り値をラベルのテキストに設定し、画面に表示する」
という処理を行っています。
・Taskクラスでの非同期処理を実装します。
/// <summary>
/// WCFメソッドを非同期で実行する
/// これまでの実装例
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
//処理中メッセージを表示
this.label1.Text = "wait...";
var callback = new Action<string>((result)=>{
this.label1.Text = result;
});
var task = new Task(() =>
{
//非同期用WCFメソッドを実行する
using (var clientService = new ServiceReference1.Service1Client())
{
//WCFメソッドの戻り値を表示
this.Invoke(callback,clientService.GetData(new Random().Next(100)));
}
});
task.Start();
}
・asyncとawaitでの非同期処理を実装します。
/// <summary>
/// WCFメソッドを非同期で実行する
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void button3_Click(object sender, EventArgs e)
{
//処理中メッセージを表示
this.label1.Text = "wait...";
//非同期用WCFメソッドを実行する
using (var clientService = new ServiceReference1.Service1Client())
{
//WCFメソッドの戻り値を表示
this.label1.Text = await clientService.GetDataAsync(new Random().Next(100));
}
}
おわりに
Taskクラスでは非同期の結果を表示するための処理が必要でした。
asyncとawaitでの非同期ではそのまま表示することができ、
直感的な実装になっています。
.NET Framework4.5以上が利用でき、非同期処理を行う必要がある場合は
asyncとawaitを積極的に利用すると良いかもしれません。
参考になれば幸いです。
よかったらクリックしてください。
にほんブログ村