[.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参照設定が必要。
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を併用した方がいいだろうな、と思う。
コメントを残す