[.NET 2] プロセス通信:サンプル

サンプルと言っても覚書。

まずはClient/Server共有のクラスを宣言する。しかしただ宣言するのではなく、InitializeLifetimeService関数をオーバーライドしないと、2分程度でIPCチャネルが解放されてしまうので注意

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting.Lifetime; // InitializeLifetimeService関数をオーバーライドするのに必要

namespace processList
{
  /// <summary>
  /// プロセス通信用クラス
  /// </summary>
  public class processListShare : MarshalByRefObject
  {
    // デリゲート宣言
    public delegate void CallEventHandler();
    // 登録用変数
    public CallEventHandler _onMsg;
    /// <summary>
    /// メッセージ(クライアント側で呼ばれる関数)
    /// もちろんpublic関数でないといけない
    /// </summary>
    public void onMsg()
    {
      if (_onMsg != null)
      {
        _onMsg();
      }
    }
    /// <summary>
    /// 有効期間初期化のオーバーライド
    /// </summary>
    /// <returns></returns>
    public override object InitializeLifetimeService()
    {
//      ILease lease = (ILease)base.InitializeLifetimeService();
//      if (lease.CurrentState == LeaseState.Initial)
//      {
//        lease.InitialLeaseTime = TimeSpan.FromMinutes(0);   // リースの初期時間を取得または設定します。既定は5分、0で無限になります
//        lease.SponsorshipTimeout = TimeSpan.FromMinutes(2); // スポンサがリースの更新時間を返すまで待機する時間を取得または設定します。
//        lease.RenewOnCallTime = TimeSpan.FromSeconds(2);    // リモート オブジェクトに対する呼び出しによって、CurrentLeaseTime が更新されるのにかかる時間を取得または設定します。
//      }
      return null; // NULLを返すことによって無限になる。leaseを返すのであれば設定されたとおりの有効期限を反映する
    }
  }
}

あとはサーバーとクライアント。サーバ側とクライアント側でIPC用のusing文が要る。また、System.Runtime.Remoting参照設定が必要。

image

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;

サーバ側

/// <summary>
/// プロセス通信用
/// </summary>
private processListShare _msg;
/// <summary>
/// IPCチャネルを作成しメッセージを待機する
/// </summary>
void server()
{
  // プロセス通信用サーバ構築
  // チャネルクラス作成
  IpcServerChannel isc = new IpcServerChannel("processList");
  // リモートオブジェクト登録
  ChannelServices.RegisterChannel(isc, true);
  // イベント登録
  _msg = new processListShare();
  // メッセージを受け取ったら実行する関数を登録する
  _msg._onMsg += new processListShare.CallEventHandler(onMsg);
  RemotingServices.Marshal(_msg, "msg", typeof(processListShare));
}

/// <summary>
/// メッセージを受け取ったら呼ばれる関数
/// もちろんpublic関数でないといけない
/// </summary>
public void onMsg()
{
  // 何かを動作させる
}

次にクライアント側

/// <summary>
/// プロセス通信用
/// </summary>
private processListShare _msg;
/// <summary>
/// IPCチャネルを作成しメッセージを送信する
/// </summary>
void client()
{
  try
  {
    // IPCチャネル作成
    IpcClientChannel icc = new IpcClientChannel();
    // リモートオブジェクト登録
    ChannelServices.RegisterChannel(icc, true);
    // オブジェクト作成
    _msg = (processListShare)Activator.GetObject(typeof(processListShare), "ipc://processList/msg");
    // 送信
    _msg.onMsg();

  }
  catch (Exception e)
  {
    MessageBox.Show(e.Message); // サーバ側でIPCチャネルが作成されていなかったら例外になる
  }
}

考えたら、こういうTips書いたの初めてかもw

サーバー側が起動しているかどうかは、同期オブジェクトMutexを併用した方がいいだろうな、と思う。

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。