いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

WCF入門-006 (基本的なサンプル, 一方向通信(IsOneWay))


WCFには、3種類の通信方法があります。

  • 要求/応答パターン
  • 一方向通信パターン
  • 双方向通信パターン(非同期)


要求/応答パターンは、今までのサンプルで利用していた
ものです。メソッドを呼び出すとサービスからの結果が返ってくるまで
待ち状態になるものです。つまり普通のメソッド呼び出しと同じ。


一方向通信パターンは、サービスメソッドを呼び出した後、結果を待ちません。
処理の中には、サービスからの結果を必要としない場合もあり、その際に利用します。


一方向通信を有効にするには、OperationContractにIsOneWay属性をtrueで設定します。
デフォルトはfalseです。

前提条件として、IsOneWay=trueとしたメソッドは戻り値の型をvoidにする必要があります。


以下、サンプルです。
まずサービス定義.今回は、一方向通信を行うものと
通常のものの2つを定義します。

どちらのメソッドも、5秒待機した後処理を終了します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;

namespace Gsf.Samples.WCF
{
    [ServiceContract(Namespace="http://Gsf.Samples.WCF")]
    public interface IMyService
    {
        // 一方向通信を行うにはIsOneWayをtrueに設定する.
        [OperationContract(IsOneWay=true)]
        void Regist();

        [OperationContract]
        void HeavyRegist();
    }
}
using System;
using System.Collections.Generic;
using System.Linq;

namespace Gsf.Samples.WCF
{
    public class MyService : IMyService
    {
        public void Regist()
        {
            Console.Write("[CALL] Regist()...");
            Wait();
            Console.WriteLine("Done.");
        }

        public void HeavyRegist()
        {
            Console.Write("[CALL] HeavyRegist()...");
            Wait();
            Console.WriteLine("Done.");
        }

        static void Wait()
        {
            System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
        }
    }
}


次にホストアプリ。

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;

namespace Gsf.Samples.WCF
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var host = new ServiceHost(typeof(MyService)))
            {
                host.Open();

                Console.WriteLine("サービスを開始しました。");
                Console.WriteLine("press <ENTER> to exit...");
                Console.ReadLine();

                host.Close();
            }
        }
    }
}


ホスト側のアプリケーション構成ファイル。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="Gsf.Samples.WCF.MyService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8086/WCFSample006/MyService"/>
          </baseAddresses>
        </host>
        <endpoint address="" 
                  binding="basicHttpBinding" 
                  contract="Gsf.Samples.WCF.IMyService" />
      </service>
    </services>
  </system.serviceModel>
</configuration>


次にクライアント側。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Diagnostics;

namespace Gsf.Samples.WCF
{
    public partial class Form1 : Form
    {
        MyServiceRef.MyServiceClient _client;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            _client = new MyServiceRef.MyServiceClient();
            ActiveControl = btnCallRegistMethod;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            _client.Close();
        }

        // 一方向通信のメソッドを呼び出し.
        private void btnCallRegistMethod_Click(object sender, EventArgs e)
        {
            Stopwatch watch = Stopwatch.StartNew();
            _client.Regist();
            watch.Stop();

            txtRegistMethodResult.Text = watch.Elapsed.ToString();
        }

        // 通常のメソッドを呼び出し.
        private void btnCallHeavyRegistMethod_Click(object sender, EventArgs e)
        {
            Stopwatch watch = Stopwatch.StartNew();
            _client.HeavyRegist();
            watch.Stop();

            txtHeavyRegistMethodResult.Text = watch.Elapsed.ToString();

        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            txtRegistMethodResult.ResetText();
            txtHeavyRegistMethodResult.ResetText();
        }
    }
}


最後にクライアント側のアプリケーション構成ファイル。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <client>
            <endpoint address="http://localhost:8086/WCFSample006/MyService" 
                      binding="basicHttpBinding" 
                      contract="MyServiceRef.IMyService" />            
        </client>
    </system.serviceModel>
</configuration>


実行すると以下のようになります。


「Registメソッド」ボタンを押下すると、一方向通信処理の処理を
「HeavyRegistメソッド」ボタンを押下すると、通常の要求/応答の処理が
それぞれ走ります。どちらのメソッドも内部では同じSleep処理が走るのに
クライアント側の呼び出し時間が全然違う事が分かります。


サンプルは以下の場所にアップしてあります。
https://sites.google.com/site/gsfzero1/Home/WCF-Sample-006.zip


================================
過去の記事については、以下のページからご参照下さい。