TCommXコンポーネントを使用し外部機器と通信するようなPGを書いていますが、送信はうまくできるのですが、受信がうまくできません。
色々としてみたのですが、受信スレッド内の
[SendMessage(CommWindow, WM_COMM_RECEIVE, WPARAM(0), LPARAM(0));]
の行ではまり込んでいるようなのです。(メッセージが無応答)
回避策などありましたらご教授ください。
使用コンパイラはDelphi7を使用していますが同現象は、Delphi6でも発生します。CommXは1.06バージョンです。
>SendMessage(CommWindow, WM_COMM_RECEIVE, WPARAM(0), LPARAM(0));]
>の行ではまり込んでいるようなのです。(メッセージが無応答)
送信スレッドが起動しないという現象があるようです。
参考
https://www.petitmonte.com/bbs/answers?question_id=3342
これを受信スレッドにも適用してみてはいかがでしょうか?
早速の回答ありがとうございます。
寄せていただいた、回答は、コンポーネントが起こした送信用スレッドに対しメッセージを流した場合のようです。
今回は、受信スレッド内から、スレッドを起動した側にメッセージを送ろうとしているのでちょっと違うようです。
PostMessageを使ってみると、一応抜けた様には見えるのですが、メッセージループの方へメッセージが流れてきません。
流れでは、CommXコンポーネント内にWndProcがあり、WindowsMessage処理をする部分があり、受信スレッドで、受信を検知すると、SendMessage(...)を使用しCommXコンポーネント内のWndProcにメッセージを通達し、受信イベントが起こるようになっているようですが、SendMessageの行でステップ実行はだんまりになってしまいます。
スレッドからSendMessageを使うことによって
デッドロックが発生しているのではないでしょうか?
参考
http://d.hatena.ne.jp/setuna-kanata/20090303/1236099867
ためしにSendMessageを全てPostMessageにしてみましたが
送信、受信ともに動くようです。
もともとこちらの環境 Delphi5 + XP では動いているので
あまり参考になりませんね。
この現象と関連あるかわかりませんが、
終了時に受信スレッドがエラーになります。
データが無いメモリを読み書きしていると表示されます。
takeさんありがとうございます。
自己解決してしまいました。
初歩的なミスでした。ステータスリクエストのロジックでループしており。
「 Application.ProcessMessages;」の行を書かなかったので、メッセージループに入ってこなかった模様です。
かなり恥ずかしい失敗をしてしまいました。
ご協力いただきありがとうございました。
Del7でも十分動きました。
こちらも色々気になっていたのでついでに調べてみました。
ポートを閉じるときのメソッド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;
まだ確認が確実ではないですが今のところこの修正で問題は起きていないようです。
takeさんありがとうございます。
色々と、ご面倒をかけ調べていただき、本当に感謝いたします。
上記の送信スレッドの件も参考にさせていただきます。
ツイート | ![]() |