TCommXの受信イベントについて

解決


dayan  2011-03-16 03:18:32  No: 40255

TCommXコンポーネントを使用し外部機器と通信するようなPGを書いていますが、送信はうまくできるのですが、受信がうまくできません。
色々としてみたのですが、受信スレッド内の
[SendMessage(CommWindow, WM_COMM_RECEIVE, WPARAM(0), LPARAM(0));]
の行ではまり込んでいるようなのです。(メッセージが無応答)
回避策などありましたらご教授ください。
使用コンパイラはDelphi7を使用していますが同現象は、Delphi6でも発生します。CommXは1.06バージョンです。


take  URL  2011-03-16 18:54:13  No: 40256

>SendMessage(CommWindow, WM_COMM_RECEIVE, WPARAM(0), LPARAM(0));]
>の行ではまり込んでいるようなのです。(メッセージが無応答)

送信スレッドが起動しないという現象があるようです。
参考
https://www.petitmonte.com/bbs/answers?question_id=3342

これを受信スレッドにも適用してみてはいかがでしょうか?


dayan  2011-03-16 22:53:10  No: 40257

早速の回答ありがとうございます。
寄せていただいた、回答は、コンポーネントが起こした送信用スレッドに対しメッセージを流した場合のようです。
今回は、受信スレッド内から、スレッドを起動した側にメッセージを送ろうとしているのでちょっと違うようです。
PostMessageを使ってみると、一応抜けた様には見えるのですが、メッセージループの方へメッセージが流れてきません。
流れでは、CommXコンポーネント内にWndProcがあり、WindowsMessage処理をする部分があり、受信スレッドで、受信を検知すると、SendMessage(...)を使用しCommXコンポーネント内のWndProcにメッセージを通達し、受信イベントが起こるようになっているようですが、SendMessageの行でステップ実行はだんまりになってしまいます。


take  URL  2011-03-16 23:48:52  No: 40258

スレッドからSendMessageを使うことによって
デッドロックが発生しているのではないでしょうか?

参考
http://d.hatena.ne.jp/setuna-kanata/20090303/1236099867

ためしにSendMessageを全てPostMessageにしてみましたが
送信、受信ともに動くようです。

もともとこちらの環境 Delphi5 + XP では動いているので
あまり参考になりませんね。

この現象と関連あるかわかりませんが、
終了時に受信スレッドがエラーになります。
データが無いメモリを読み書きしていると表示されます。


dayan  2011-03-17 03:21:56  No: 40259

takeさんありがとうございます。
自己解決してしまいました。
初歩的なミスでした。ステータスリクエストのロジックでループしており。
「 Application.ProcessMessages;」の行を書かなかったので、メッセージループに入ってこなかった模様です。
かなり恥ずかしい失敗をしてしまいました。
ご協力いただきありがとうございました。
Del7でも十分動きました。


take  2011-03-17 18:16:43  No: 40260

こちらも色々気になっていたのでついでに調べてみました。

ポートを閉じるときのメソッドPortCloseに問題があるように思えます。

送信スレッドの終了を待たずに終わっているため
シリアルポートに何もつながないで、データ送信待ちが続いたまま
終了するようなときに、メモリ解放が出来ていないのではと推測します。

内蔵シリアルポートではメモリエラー程度でしたが
仮想シリアルポートでは最悪の場合ブルースクリーンになるようです。

上記の現象は終了時に発生するもので、動作中は問題ありません。

----------- 修正前 -------------------------
    if TransThread <> Nil then begin
      TransThread.Terminate;                                // 送信スレッド終了
    end;
----------- 修正後 -------------------------
    if TransThread <> Nil then begin
      TransThread.Terminate;                                // 送信スレッド終了
      while not TransThread.FreeOnTerminate do begin
        Application.ProcessMessages();
      end;
    end;

まだ確認が確実ではないですが今のところこの修正で問題は起きていないようです。


dayan  2011-03-17 18:30:59  No: 40261

takeさんありがとうございます。
色々と、ご面倒をかけ調べていただき、本当に感謝いたします。
上記の送信スレッドの件も参考にさせていただきます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加