WCF Webサービスを非同期に呼び出す - C#

WCF Webサービスを非同期に呼び出すコードを紹介します。

概要

こちらの記事ではWindows FormアプリケーションからWCFサービスを同期呼び出しで呼び出すコードを紹介しました。通常の呼び出しであれば同期呼び出しでも問題ありませんが、処理に時間がかかる、あるいは通信帯域が狭い場合、レスポンスに長い時間がかかる場合があります。同期呼び出しの場合レスポンスを待っている間はUIがロックされてしまうため、レスポンス時間が長くなる場合は非同期での呼び出しをする必要があります。この記事では、WCF Webサービスを非同期で呼び出す手順とコードを紹介します。

プログラム例

Visual Studio でWindows Formアプリケーションを作成します。

サービス参照の追加

ソリューション エクスプローラーのウィンドウでプロジェクトノード内の[参照]ノードをクリックして選択し、右クリックします。ポップアップメニューが表示されますので、[サービス参照の追加]メニューをクリックします。


[サービス参照の追加]ダイアログが表示されます。


ウィンドウ上部の[アドレス]欄にWCFサービスのURLを入力します。入力後[移動]ボタンをクリックします。サービスが取得されます。ウィンドウ下部の[名前空間]のテキストボックスにサービスを参照するためのネームスペースを設定します。今回は"iPentecSimpleWcfServiceReference"と設定します。設定後[OK]ボタンをクリックします。

UI

下図のUIを作成します。テキストボックス2つとボタンを1つ配置します。

コード

2パターンの記述方法を紹介します。どちらも同じ動作になります。

async await を利用する例

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 WcfServiceAsyncCall
{
  public partial class FormMain : Form
  {
    public FormMain()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      WcfProc1();
    }

    private async void WcfProc1()
    {
      iPentecSimpleWcfServiceReference.Service1Client client = new iPentecSimpleWcfServiceReference.Service1Client();
      string result = await client.HelloProcAsync(textBox1.Text);
      textBox2.Text = result;
    }
  }
}

解説

awaitを利用するため、メソッドの定義部分に async キーワードを記入します。
  private async void WcfProc1()

下記コードでサービスのクライアントオブジェクトを作成します。
  iPentecSimpleWcfServiceReference.Service1Client client = new iPentecSimpleWcfServiceReference.Service1Client();

下記コードでWCFサービスのWebメソッドを呼び出します。クライアントオブジェクトのメソッドを呼び出すことでWCFのWebメソッドを呼び出せます。awaitを付けて呼び出すことで並列処理になります。Webメソッドの戻り値がクライアントオブジェクトのメソッドの戻り値となります。
Webメソッドの戻り値を下部のテキストボックスに表示します。
  string result = await client.HelloProcAsync(textBox1.Text);
  textBox2.Text = result;

async await を利用しない例

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 WcfServiceAsyncCall
{
  public partial class FormMain : Form
  {
    public FormMain()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      WcfProc2();
    }

    private void WcfProc2()
    {
      iPentecSimpleWcfServiceReference.Service1Client client = new iPentecSimpleWcfServiceReference.Service1Client();
      Task<string> task = client.HelloProcAsync(textBox1.Text);
      task.Wait();

      textBox2.Text = task.Result;
    }
  }
}

解説

下記コードでサービスのクライアントオブジェクトを作成します。
  iPentecSimpleWcfServiceReference.Service1Client client = new iPentecSimpleWcfServiceReference.Service1Client();

下記コードでWCFサービスのWebメソッドを呼び出します。クライアントオブジェクトのメソッドを呼び出すことでWCFのWebメソッドを呼び出せます。非同期実行となるため、すぐにはWebメソッドの結果は戻らないため、クライアントオブジェクトのメソッドの戻り値はTaskオブジェクトとなります。
  Task<string> task = client.HelloProcAsync(textBox1.Text);

下記のコードで非同期実行された HelloProcAsync() の完了を待ちます。
  task.Wait();

Webメソッドの戻り値を下部のテキストボックスに表示します。Webメソッドの戻り値は、TaskオブジェクトのResultプロパティに代入されています。
  textBox2.Text = task.Result;

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。


上部のテキストボックスに入力文字列を入力します。今回は「もふもふアヒル」の文字列を入力しました。


[button1]をクリックします。下部のテキストボックスにWebメソッドの結果の文字列が表示されます。入力文字列の前に「こんにちは」の文字列が追加され、入力文字列の後ろに「さん」が追加されていることが確認できます。Webメソッドの処理が実行できていることがわかります。


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2018-06-20
作成日: 2018-05-29
iPentec all rights reserverd.