/// <summary>サーバ起動 - pollingスレッド関数</summary>
        private void PollingSharedMemory(object o)
        {
            // 共有メモリ(サーバ)
            SharedMemory sm = null;

            // スレッドID
            int managedThreadId = Thread.CurrentThread.ManagedThreadId;

            try
            {
                // 共有メモリを生成
                sm = new SharedMemory("my-sm", 256, "my-mtx");

                // マップ
                sm.Map(0, 0);

                // Polling開始を表示
                this.SetResult_Svr(
                    string.Format("Polling開始! - ThreadId:{0}", managedThreadId));

                // Polling処理

                while (!End)
                {
                    byte[] byt = null;
                    sm.GetMemory(out byt, 0);
                    //int msg = BitConverter.ToInt32(byt, 0);
                    short msg = BitConverter.ToInt16(byt, 0);

                    // 受信メッセージを表示
                    this.SetResult_Svr(
                        string.Format("({0})受信:{1}", managedThreadId, msg.ToString()));

                    Thread.Sleep(0); // Polling間隔
                }

                // Polling停止を表示
                this.SetResult_Svr(
                    string.Format("Polling停止! - ThreadId:{0}", managedThreadId));
            }
            catch (Exception ex)
            {
                // エラーを表示
                this.SetResult_Svr(
                    string.Format("({0})エラー:{1}", managedThreadId, ex.ToString()));
            }
            finally
            {
                if (sm != null)
                {
                    // 共有メモリをクローズ
                    // アンロック&マネージ・アンマネージリソースの解放
                    sm.Close();// ←コメントアウトするとGC任せになるが、ミューテックスの解放が遅れる!
                }
            }
        }
        /// <summary>クライアント生成 - ReadWriteスレッド関数</summary>
        private void ReadWriteSharedMemory(object o)
        {
            //while (this.LoopFlg)
            //{
            //// 0ミリ寝る。
            //Thread.Sleep(0);

            // 共有メモリ(サーバ)
            SharedMemory sm = null;

            // スレッドID
            int managedThreadId = Thread.CurrentThread.ManagedThreadId;

            try
            {
                // 共有メモリを生成(256バイト)
                sm = new SharedMemory("my-sm", 256, "my-mtx");

                // マップ
                sm.Map(0, 0);

                while (this.LoopFlg)
                {
                    // 0ミリ寝る。
                    Thread.Sleep(0);

                    // ロック
                    sm.Lock();

                    // 受信(バイト → int)
                    byte[] rcvByte = null;
                    sm.GetMemory(out rcvByte, 0);
                    //int i = BitConverter.ToInt32(rcvByte, 0);
                    short i = BitConverter.ToInt16(rcvByte, 0);

                    // 受信メッセージを表示
                    this.SetResult_Client(
                        string.Format("({0})受信:{1}", managedThreadId, i.ToString()));

                    // 送信(int → バイト)
                    byte[] sndByte = null;

                    // 共有メモリを初期化
                    sm.SetMemory(this.InitBuff(256), 256);

                    // (++i)を送信
                    sndByte = BitConverter.GetBytes(++i);
                    sm.SetMemory(sndByte, sndByte.Length);
                    //sm.SetMemory(sndByte, sndByte.Length);

                    // 送信メッセージを表示
                    this.SetResult_Client(
                        string.Format("({0})送信:{1}", managedThreadId, i.ToString()));

                    // アンロック
                    sm.Unlock();
                }
            }
            catch (Exception ex)
            {
                // エラーを表示
                this.SetResult_Client(
                    string.Format("({0})エラー:{1}", managedThreadId, ex.ToString()));
            }
            finally
            {
                if (sm != null)
                {
                    // 共有メモリをクローズ
                    // アンロック&マネージ・アンマネージリソースの解放
                    sm.Close();// ←コメントアウトするとGC任せになるが、ミューテックスの解放が遅れる!
                    // 二重解放となった場合の例外は内部で潰す。
                }
            }
            //}
        }
        /// <summary>サーバ起動 - pollingスレッド関数</summary>
        /// <remarks>unsafeキーワードが必要になる</remarks>
        private void PollingSharedMemory()
        {
            // 共有メモリ(サーバ)
            SharedMemory sm = null;

            // スレッドID
            int managedThreadId = Thread.CurrentThread.ManagedThreadId;

            try
            {
                // 共有メモリを生成
                sm = new SharedMemory("my-sm", 256, "my-mtx");

                // マップ
                sm.Map(0, 0);

                // Polling開始を表示
                this.SetResult_Svr(
                    string.Format("Polling開始! - ThreadId:{0}", managedThreadId));

                // Polling処理

                while (!End)
                {
                    // システム時間、ローカル時間の「Manage SYSTEMTIME構造体」
                    SYSTEMTIME cst = new SYSTEMTIME();

                    byte[] cstBytes = new byte[Marshal.SizeOf(cst)];
                    byte[] cstsBytes = new byte[Marshal.SizeOf(cst) * 2];

                    // 共有メモリから「Unmanage SYSTEMTIME構造体」配列のバイト表現を読み込む。
                    sm.GetMemory(out cstsBytes, cstsBytes.Length);

                    // マーシャリング(「Unmanage SYSTEMTIME構造体」配列のバイト表現を「Manage SYSTEMTIME構造体」へ変換)

                    //// (1)
                    //object[] os = new object[2];

                    //Array.Copy(cstsBytes, 0, cstBytes, 0, Marshal.SizeOf(cst));
                    //os[0] = CustomMarshaler.BytesToStructure(cstBytes, typeof(SYSTEMTIME));

                    //Array.Copy(cstsBytes, Marshal.SizeOf(cst) * 1, cstBytes, 0, Marshal.SizeOf(cst));
                    //os[1] = CustomMarshaler.BytesToStructure(cstBytes, typeof(SYSTEMTIME));

                    // (2)
                    object[] os = CustomMarshaler.BytesToStructures(cstsBytes, typeof(SYSTEMTIME), 2);

                    SYSTEMTIME[] csts = new SYSTEMTIME[] { (SYSTEMTIME)os[0], (SYSTEMTIME)os[1] };

                    // システム時間
                    string systemTime =
                        string.Format("{0:0000}/{1:00}/{2:00} {3:00}:{4:00}:{5:00}.{6:000}",
                            csts[0].Year, csts[0].Month, csts[0].Day,
                            csts[0].Hour, csts[0].Minute, csts[0].Second, csts[0].Milliseconds);

                    // ローカル時間
                    string localTime =
                        string.Format("{0:0000}/{1:00}/{2:00} {3:00}:{4:00}:{5:00}.{6:000}",
                            csts[1].Year, csts[1].Month, csts[1].Day,
                            csts[1].Hour, csts[1].Minute, csts[1].Second, csts[1].Milliseconds);

                    // 受信メッセージを表示
                    this.SetResult_Svr(
                        string.Format("({0})受信:{1}", managedThreadId,
                        "\r\nsystemTime:" + systemTime + "\r\nlocalTime:" + localTime));

                    Thread.Sleep(1000); // Polling間隔
                }

                // Polling停止を表示
                this.SetResult_Svr(
                    string.Format("Polling停止! - ThreadId:{0}", managedThreadId));
            }
            catch (Exception ex)
            {
                // エラーを表示
                this.SetResult_Svr(
                    string.Format("({0})エラー:{1}", managedThreadId, ex.ToString()));
            }
            finally
            {
                if (sm != null)
                {
                    // 共有メモリをクローズ
                    // アンロック&マネージ・アンマネージリソースの解放
                    sm.Close();// ←コメントアウトするとGC任せになるが、ミューテックスの解放が遅れる!
                }
            }
        }