• 締切済み

シリアル通信におけるプログラム終了が遅い件

今、Visual Basic6.0でシリアル通信を行うプログラムを作成しています。完成後に実行させると思い通りに端末からのデータを表示してくれるのですが、[切断]といったポートを閉じる操作をしたときにプログラムが終了するまでに30秒から40秒ほどかかってしまいます。ソースを書き直して再度実行するなど、終了するたびに毎回同じくらいの時間がかかります。Windowsのハイパーターミナルでもデータの受信・表示ができる上、[切断]ですぐに終了するのですが、自作のプログラムではそうはいきません。解決方法をよろしくお願いいたします。

みんなの回答

  • takasebou
  • ベストアンサー率42% (61/144)
回答No.7

これは恐らく通信状況の問題のようですね。たぶん電文受信待ち状態で切断しようとした時に時間待ちが発生するという事ですね。 ちなみにタイマーを使ってはいけないという事ではないですよ。システムによっては、その方がいい場合もあるでしょうね。しかしタイマー処理よりも別の方法にした方がベターです。 コミュニケーションオブジェクトは、データが送信されてくると、OnCommイベントが発生しますから、そのイベントをもってデータの受信を行った方がいいと思います。 たぶん#1の方がいわれているようにタイムアウト待ちしているんだと思いますよ。 例えばURLのサイト等参考にしてみてください。参考に出来るソースもダウンロード出来るようです。 MSComm でGoogleなどで検索すれば、沢山この手のサイトは出てくると思いますので、そちらを参考にしながら進めるのがいいと思います。 がんばってくださいね。

参考URL:
http://speana-1.hp.infoseek.co.jp/vb/vb_5/vb_5.htm
nw_lab
質問者

お礼

いろいろお世話になりました。参考サイトをもとに、Oncommイベントで試してみたいと思います。ありがとうございました。

  • takasebou
  • ベストアンサー率42% (61/144)
回答No.6

Private Sub BtnEnd_Click() IF MSComm1.PortOpen = True Then MSComm1.PortOpen = False End if Unload Me End Sub とりあえず、こういった形にしてみてください。 なお一応私の方で同様のソースで試してみたところ、現象を再現出来ませんでした。実際にはこの他にソースがありませんか?

nw_lab
質問者

補足

遅くなりまして申し訳ございません。ソースに関しまして、補足させて頂きます。 -------------------------------------------------- Private Sub Form_Load() MSComm1.CommPort = 3 MSComm1.Settings = "9600,N,8,1" MSComm1.InputMode = comInputModeText If (MSComm1.PortOpen = False) Then MSComm1.PortOpen = True End If End Sub Private Sub BtnSrt_Click() Timer1.Interval = 5000 End Sub Private Sub BtnEnd_Click() Timer1.Enabled = False If (MSComm1.PortOpen = True) Then MSComm1.PortOpen = False End If Set Form = Nothing End Sub Private Sub Timer1_Timer() RichTextBox1.Text = MSComm1.Input End Sub ------------------------------------------------- takasebou様の1つ前のご回答の時に、通信にタイマーを使っていないかということでしたが、実は使っていたときのほうが安定しておりました。ですが、使わないほうがいいのかと思い、タイマーを使っていないソースでご返信をいたしました。ところが、上記のソースだとテキストボックスに受信内容が表示されます。終了時の問題はまだ未解決ですが、私のほうで[受信][終了]ボタンの間にタイマーをとめるための[切断]を作り、最初の1,2回は即終了するという良い結果を得ました。しかし、なぜかそれ以降、即終了することはなく、未だに40秒程経過するのを待たないとプログラムが終了しない状況でございます。 何度も申し訳ございませんが、よろしくお願い申し上げます。

  • takasebou
  • ベストアンサー率42% (61/144)
回答No.5

#2です とりあえずset Form = Nothingは消してみてください。Formとかコマンドボタンとかの実際に画面上に設置してるオブジェクトは別に解放しなくてもいいです。 Set obj = …… で設定したオブジェクトに関して解放してあげてください。あと終了ボタン押した時の処理は Unload Meで終了しませんか? Endステートメントは避けた方がいいです。 あとまぁ切断ボタンを作らなくても、終了ボタンを押した一連の流れの中で切断処理を行えばいいかとは思います。 private Sub cmdEnd_Click() a.close  ← ポートクローズ unload me ← フォームのアンロード End Sub こんな感じで。まぁ、たぶんこれくらいのプログラムだと使ったからどうという訳でもないですが、他と連携するようなログラムになってくると思わぬ動作を引き起こす可能性もあります。 で、肝心の速度が遅い件ですが、どうやら切断する時に切断処理に時間がかかっているようですね。 と、いう事は具体的なコードがないと判断が難しいです。 接続-通信-切断を実際のコードでどのように処理しているのでしょうか。通信に関しては、もしかしてタイマーでくるくる回していますか? その場合は先にタイマーを止めてみましょう。tmrObj.Enabled =False等。 後は具体的にコードをある程度書いていただかないと(一概にシリアル通信といっても、いろいろやり方があるので)、判断が難しいです。

nw_lab
質問者

補足

ご回答を受けまして修正した部分は元に戻して記載します。なにぶん初心者ですので、ソースには不十分な部分が多いかと思います。よろしくお願いいたします。 ------------------------------------------------------------ Private Sub Form_Load() MSComm1.CommPort = 3 MSComm1.Settings = "9600,N,8,1" MSComm1.InputMode = comInputModeText If (MSComm1.PortOpen = False) Then MSComm1.PortOpen = True End If End Sub Private Sub BtnSrt_Click() '受信内容の表示 RichTextBox1.Text = MSComm1.Input End Sub Private Sub BtnEnd_Click() End End Sub

  • takasebou
  • ベストアンサー率42% (61/144)
回答No.4

すみません、下で#1です。と書きましたが、#2ですの間違いでした(^^;

  • takasebou
  • ベストアンサー率42% (61/144)
回答No.3

#1です。 通信プログラムの前提として アプリ起動-接続-通信-切断-アプリ終了 というのは一連の流れとして、必ず実行しなくてはならない流れです。 ですので、切断せずにアプリを終了させようとすると通信を何とか続行しようとして時間がかかっている可能性がありますね。 ちなみにEndステートメントは強制的にプログラムを終了させるコマンドなので、あまり通常時に使用するのは望ましくないので使わない方が無難です。もっているオブジェクトを強制的に破棄するので、その時点でどのような動作をするかわからないからです。 どうしても必要な場合を除いて、開いているフォームを全てUnloadする事で終了させるようにした方が望ましいです。また何かオブジェクトや動的配列を使用していれば、そちらは解放(set obj = nothing や Erase a()等)してからUnloadする必要があります。

nw_lab
質問者

補足

度々申し訳ありません。ご回答を受けてプログラム中では、[受信]、[切断]、[終了]という3つのボタンを設け、[切断]にてポートクローズとSet Form = nothing をするようにしました。そして、[終了]でEndをするようにしてあります。受信後に[切断]を押すとマウスポインタが砂時計表示になり、フォーム上部に(応答なし)の表示が出てしまいます。数秒待てば[終了]を押すことが可能になりますが、やはり、切断から終了までの流れには時間がかかってしまう状況です。 よろしくお願いいたします。

  • takasebou
  • ベストアンサー率42% (61/144)
回答No.2

終了する時にまず接続を切ってから終了していますか?

nw_lab
質問者

補足

これはつまり、プログラムを終了させる前にポートを閉じる操作をすればいいということでしょうか?現状では、[終了]というボタン操作でEndするようにしているだけなので、ポートクローズしていない可能性が出てきました^^;

回答No.1

シリアル通信を、常時受信中にしていませんか? データの有無を確認してから受信しないと タイムアウトになるまで戻ってきません。

nw_lab
質問者

補足

Form_loadにおいて、ポート番号の指定・通信速度などの設定・テキスト受信モード設定・ポートオープンをさせています。それから[受信]をクリックした際にテキストボックスに受信データを表示させる仕組みなのですが、ある任意の時に[切断]を押して終了する場合に時間がかかってしまう状況です。なお、データは常に次から次へと新しいものが発生するため、データが無い状態にはならないものです。 補足として質問させて頂きますので、改めてよろしくお願いいたします。

関連するQ&A