【メモ】プロセス間通信時に、スレッド違い云々のエラーで苦しむ

 

IPCでのプロ節間通信を用いて、プログラム間でデータのやり取りを実現する。

各種方法は、ググってください。

サーバとクライアントの実装が形なりにもできて実行した。

このコントロールで実行されている動作は、間違ったスレッドから呼び出されています。この動作を実行するには、control.invoke または control.begininvoke を使って正しいスレッドにマーシャリングしてください。

こんなエラーが、クライアントのテストを行った時に発生した。当初、元となるプログラム(EXE)から動的に組み込まれた(DLL)から、参照設定したフォームを呼び出していたために、発生したエラーだと考えた。

6時間ほど悩んだが、解決策が出てこない。サンプルで参照しているMSDNでのサンプルソースでは同じエラーが発生しない。

6時間ほど悩んで、プロセス間通信もパイプを使った方法に変更しようかと考え始めていたが、サーバ側に問題が発生していないか確認を行った。

言い訳になるが、サーバ側に問題がないと判断したのは、MSDNのサンプルのまま動かしているだけで、クライアントを変えれば接続ができていた(実は、ここが問題)。

デバッグを行ってみて、問題個所が解った。

サーバ側で、IPCのイベントからデータを受け取った後で、フォームにセットする場所で、上記エラーが発生していた。

            if( listBox.InvokeRequired == true )
            {
                Invoke(new Action(() =>
                {
                    listBox.Items.Add(strReceve);
                }));
            }
            else
            {
                listBox.Items.Add(strReceve);
            }

こんな感じで、Invokeを使う必要があるか確認を行ってから、アクションを行うように修正した。これで、問題の箇所のエラーが出なくなったが、ネットに転がっている情報やMSDNのサンプルには同様の現象が確認されていない。

また、IPCのサンプルを上げているサイトで多いのが、チャンネルの作成は、”一度通せばOK”みたいな記述があるが、運営として考える時には、一度で問題はないが、プログラムは起動を繰り返すことが多い。その場合に、接続エラーやチャンネルの起動エラーなどが発生する。

            // IPC Channelを作成
            IpcServerChannel serverChannel = new IpcServerChannel("storyvideoservice");
            //
            // リモートオブジェクトを登録
            ChannelServices.RegisterChannel(serverChannel, true);

この部分は、serverChannelを登録して終わりにしてしまっている。IpcServerChannel serverChannel を、private で宣言をして、フォームが閉じる時などで、チャンネルの登録解除を行っておくと、問題が解決した。

            ChannelServices.UnregisterChannel(serverChannel);

これで、問題は解決しているが、検証を行うために作っただけで、実際にデータ連携を含めて作ると別の問題が発生するかもしれない。

ひとまずは、これでプロセス間通信のイベントが発生できて、使えそうだとわかった。

開発に関してや、時事ネタ。F1関連の戯言を呟いています。
小説アカウントでは、宣伝をメインに積読本や購入予定の書籍を呟いています。