■Webサービスを非同期で呼び出す

前回の「▼実践1-1 ClickOnceのリモート処理 - ASP.NET XML Webサービスを使用してみよう!」ではClickOnceアプリからWebサービスの呼び出しを行いました。前回はWebサービスの同期呼び出しを行いましたが、同期呼び出しは、サーバーとの通信とWebサービスの処理そのものが終了するまで待機するため、その間に発生するクライアント側でのイベントの処理が遅れてしまう可能性があります。そもそもWebサービスの呼び出しに限らず、時間のかかるイベント処理を、イベント処理用に待機しているスレッドで行う事は望ましくないのです。そこで今回は、Webサービスの非同期呼び出しを行ってみたいと思います。

前回の実践1-1で、Web参照を追加した時、自動的に[SampleService」というクラスが追加されました。このクラスはVisualStudioが 自動的に作成したクラスで、サーバーとの通信を受け持ってくれるProxyの役割を果たします。実はこのクラスには「Hello」というWebサービス側で定義したメソッドの他に、「BeginHello」と「EndHello」というメソッドが追加されています。これらのメソッドは一つのWebMethodに対して必ずProxy側に自動的に生成されるメソッドで、これらのメソッドを使用することにより、Webサービスの 非同期呼び出しを実現できるのです。

非同期呼び出しを行う方法はいくつか有るのですが、今回サンプルとしてコールバックメソッドを使用する 方法をご紹介します。コールバックメソッドを使用する場合、呼び出し側はまず、「Begin×××」が先頭に付くメソッドを 呼び出します。クライアント側のスレッドはサーバ側の処理が終了するまで待機を行わず、即座に次の処理に進みます。 そして、サーバ側で処理が終了すると、「Begin×××」をコールした時に引数で指定したメソッドが呼び出されます。 ここまでの流れのソースを以下に示します。

        private void sendButton_Click(object sender, EventArgs e)
        {
            SampleService service = new SampleService();
            //Webサービスの呼び出しを行い、クライアント側の処理を継続する。
            service.BeginHello(nameText.Text,new AsyncCallback(serviceCallBack),service);
        }

BeginHelloの第一引数はHelloメソッドの第一引数と同じです。第二引数にコールバックメソッドを指定します。その際、デリゲート 「AsyncCallback」を使用します。最後の引数には、コールバックメソッド内で参照したいオブジェクトを指定するのですが、通常、 WebサービスのProxyクラスのインスタンスを指定します。今回の例のように「Begin×××」の引数はメソッド本来の引数に コールバックメソッドとコールバックメソッド内で参照するオブジェクトが追加されたものになります。 次にコールバックメソッドの内容を見ていきます。

        private void serviceCallBack(IAsyncResult ar)
        {
            SampleService service = (SampleService)ar.AsyncState;
            //Webサービスの処理結果を取得する
            String result = service.EndHello(ar);

            MessageBox.Show(result);
        }

まず、コールバックメソッドは必ず引数にIAsyncResultを取ります。IAsyncResultのAsyncStateから呼び出し時の最後の引数で 指定したオブジェクトを取得する事ができます。そして、AsyncStateから取得したサービスのProxyクラスのEndHello()を 呼び出し目的の結果を取得します。

HOMEへ