/// <summary>非同期イベント通知</summary> /// <param name="dstEventClass">送信先イベント区分(最大36文字)</param> /// <param name="dstFuncID">送信先機能ID(最大36文字)</param> /// <param name="srcEventClass">送信元イベント区分(最大36文字)</param> /// <param name="srcFuncID">送信元機能ID(最大36文字)</param> /// <param name="dstPipeName">送信先 名前付きパイプ名</param> /// <param name="srcPipeName">送信元 名前付きパイプ名</param> /// <param name="dataLength">データ部のバイト長</param> /// <param name="bodyBytes">データ部のバイト表現</param> /// <returns> /// ・成功:true /// ・失敗:false(名前付きパイプ クライアントが見つからない) /// </returns> /// <remarks>スレッド セーフ</remarks> public static bool SendAsyncEvent( AsyncEventEnum.EventClass dstEventClass, string dstFuncID, AsyncEventEnum.EventClass srcEventClass, string srcFuncID, string dstPipeName, string srcPipeName, uint dataLength, byte[] bodyBytes) { lock (AsyncEventFx._lock) // staticなのでロックする。 { if (AsyncEventFx.NPCS.ContainsKey(dstPipeName)) { // 名前付きパイプ クライアントを取得 NamedPipeClient npc = AsyncEventFx.NPCS[dstPipeName]; // ヘッダ部のバイト表現を生成 // ヘッダ部を生成 AsyncEventHeader aeh = new AsyncEventHeader( dstEventClass, dstFuncID, srcEventClass, srcFuncID, srcPipeName, dataLength); // ヘッダ部のマーシャリング byte[] headerBytes = CustomMarshaler.StructureToBytes(aeh); // ヘッダ・データ部のバイト表現をマージ byte[] bytes = new byte[headerBytes.Length + bodyBytes.Length]; Array.Copy(headerBytes, bytes, headerBytes.Length); Array.Copy(bodyBytes, 0, bytes, headerBytes.Length, bodyBytes.Length); // Threadを生成してThread関数(SendData)を実行 Thread th = new Thread(npc.SendData); th.Start(bytes); return(true); } else { return(false); } } }
/// <summary>非同期イベント通知</summary> /// <param name="dstEventClass">送信先イベント区分(最大36文字)</param> /// <param name="dstFuncID">送信先機能ID(最大36文字)</param> /// <param name="srcEventClass">送信元イベント区分(最大36文字)</param> /// <param name="srcFuncID">送信元機能ID(最大36文字)</param> /// <param name="dstPipeName">送信先 名前付きパイプ名</param> /// <param name="srcPipeName">送信元 名前付きパイプ名</param> /// <param name="dataLength">データ部のバイト長</param> /// <param name="bodyBytes">データ部のバイト表現</param> /// <returns> /// ・成功:true /// ・失敗:false(名前付きパイプ クライアントが見つからない) /// </returns> /// <remarks>スレッド セーフ</remarks> public static bool SendAsyncEvent( AsyncEventEnum.EventClass dstEventClass, string dstFuncID, AsyncEventEnum.EventClass srcEventClass, string srcFuncID, string dstPipeName, string srcPipeName, uint dataLength, byte[] bodyBytes) { lock (AsyncEventFx._lock) // staticなのでロックする。 { if (AsyncEventFx.NPCS.ContainsKey(dstPipeName)) { // 名前付きパイプ クライアントを取得 NamedPipeClient npc = AsyncEventFx.NPCS[dstPipeName]; // ヘッダ部のバイト表現を生成 // ヘッダ部を生成 AsyncEventHeader aeh = new AsyncEventHeader( dstEventClass, dstFuncID, srcEventClass, srcFuncID, srcPipeName, dataLength); // ヘッダ部のマーシャリング byte[] headerBytes = CustomMarshaler.StructureToBytes(aeh); // ヘッダ・データ部のバイト表現をマージ byte[] bytes = new byte[headerBytes.Length + bodyBytes.Length]; Array.Copy(headerBytes, bytes, headerBytes.Length); Array.Copy(bodyBytes, 0, bytes, headerBytes.Length, bodyBytes.Length); // Threadを生成してThread関数(SendData)を実行 Thread th = new Thread(npc.SendData); th.Start(bytes); return true; } else { return false; } } }
/// <summary>サーバ起動 - listenerスレッド関数</summary> private void ListeningNamedPipeServer() { try { // ヘッダ部のバッファを用意 byte[] buff = new byte[CustomMarshaler.StructureToBytes(new AsyncEventHeader()).Length]; while (this.loop)// 停止されるまでループ { // 名前付きパイプ サーバ ストリーム×1(待機) this.NPSS = new NamedPipeServerStream(this.NPSS_Name, PipeDirection.In, 1); this.NPSS.WaitForConnection(); #region 受信処理 // 通知処理は非同期化する if (this.NPSS.Read(buff, 0, buff.Length) == 1) { // 制御文字を受信 byte b = buff[0]; // 1バイトの書き込みは制御文字 // 制御コードとしては、0-256を利用可能 switch (Convert.ToUInt16(b)) { case 0: // 終了 return; //case 1-256: // break; default: // 現在の接続を切断してから、 this.NPSS.Disconnect(); this.NPSS.Close(); continue; // ★ continue(whileに対応) } } else { // ヘッダ部を受信 // データ部のマーシャリング AsyncEventHeader aeh = (AsyncEventHeader) CustomMarshaler.BytesToStructure(buff, typeof(AsyncEventHeader)); // データ部のバッファを用意 byte[] bodyBytes = new byte[aeh.DataLength]; // データ部を受信 if (this.NPSS.Read(bodyBytes, 0, bodyBytes.Length) == bodyBytes.Length) { // 正常 } else { // 異常 // デバッグ出力 Debug.WriteLine( "受信した非同期イベントのデータ部の長さに不正があります。"); // 現在の接続を切断してから、 this.NPSS.Disconnect(); this.NPSS.Close(); continue; // ★ continue(whileに対応) } #region 非同期イベント通知処理 // ここは、シングルトンだが、スレッド関数で、 // 呼出元から切り離されるのでロック必要(AEES参照) lock (this) { // 即切り離し string dstFuncID = (new string(aeh.DstFuncID)).Trim(); if (this.AEES.ContainsKey(dstFuncID)) { List <AsyncEventEntry> aee_lst = (List <AsyncEventEntry>) this.AEES[dstFuncID]; // 全エントリ(デレゲード)にブロードキャスト。 foreach (AsyncEventEntry aee in aee_lst) { if ((int)aee.EventClass == aeh.DstEventClass) // イベント区分のチェック { #region 非同期呼び出し(区分ごとに呼び方が変わる) // 引数 object param = new object[] { aeh, bodyBytes }; switch ((int)aee.EventClass) { case (int)AsyncEventEnum.EventClass.Thread: // Thread // ワーカ系(Thread) // Thread.Start メソッド (Object) Thread th = new Thread((ParameterizedThreadStart)aee.Callback); th.Start(param); break; case (int)AsyncEventEnum.EventClass.ThreadPool: // ThreadPool // ワーカ系(ThreadPool) // ThreadPool.QueueUserWorkItem メソッド (WaitCallback, Object) ThreadPool.QueueUserWorkItem( (WaitCallback)aee.Callback, param); break; case (int)AsyncEventEnum.EventClass.WinForm: // WinForm // GUI系(Windows Forms) // Control.BeginInvoke メソッド (Delegate, Object[]) ((Control)(aee.Control)).BeginInvoke( (SetResultDelegate)aee.Callback, param); break; case (int)AsyncEventEnum.EventClass.WPF: // WPF // GUI系(WPF) // Dispatcher.BeginInvoke メソッド (Delegate, Object[]) ((DependencyObject)(aee.Control)).Dispatcher.BeginInvoke( (SetResultDelegate)aee.Callback, param); break; default: break; } #endregion } else { // デバッグ出力 Debug.WriteLine("非同期イベントのイベント区分が不一致です。"); // 現在の接続を切断してから、 this.NPSS.Disconnect(); this.NPSS.Close(); break; // ★ foreachに対応 } } } } #endregion } #endregion // 現在の接続を切断してから、 this.NPSS.Disconnect(); this.NPSS.Close(); } } catch (Exception ex) { // デバッグ出力 Debug.WriteLine("ListeningNamedPipeServer" + "でエラーが発生しました。:" + ex.ToString()); } finally { if (this.NPSS != null) { // 名前付きパイプ サーバ ストリームをクローズ this.NPSS.Close(); } } }