/// <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();
                    }
                }
            }