こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

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

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

投稿日時 - 2006-01-16 13:04:45

QNo.1899762

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(7)

ANo.7

これは恐らく通信状況の問題のようですね。たぶん電文受信待ち状態で切断しようとした時に時間待ちが発生するという事ですね。

ちなみにタイマーを使ってはいけないという事ではないですよ。システムによっては、その方がいい場合もあるでしょうね。しかしタイマー処理よりも別の方法にした方がベターです。

コミュニケーションオブジェクトは、データが送信されてくると、OnCommイベントが発生しますから、そのイベントをもってデータの受信を行った方がいいと思います。

たぶん#1の方がいわれているようにタイムアウト待ちしているんだと思いますよ。

例えばURLのサイト等参考にしてみてください。参考に出来るソースもダウンロード出来るようです。

MSComm でGoogleなどで検索すれば、沢山この手のサイトは出てくると思いますので、そちらを参考にしながら進めるのがいいと思います。

がんばってくださいね。

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

投稿日時 - 2006-01-23 11:17:39

お礼

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

投稿日時 - 2006-02-12 10:22:39

ANo.6

Private Sub BtnEnd_Click()
IF MSComm1.PortOpen = True Then
MSComm1.PortOpen = False
End if
Unload Me
End Sub

とりあえず、こういった形にしてみてください。

なお一応私の方で同様のソースで試してみたところ、現象を再現出来ませんでした。実際にはこの他にソースがありませんか?

投稿日時 - 2006-01-17 20:37:13

補足

遅くなりまして申し訳ございません。ソースに関しまして、補足させて頂きます。
--------------------------------------------------
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秒程経過するのを待たないとプログラムが終了しない状況でございます。
何度も申し訳ございませんが、よろしくお願い申し上げます。

投稿日時 - 2006-01-22 16:52:22

ANo.5

#2です

とりあえずset Form = Nothingは消してみてください。Formとかコマンドボタンとかの実際に画面上に設置してるオブジェクトは別に解放しなくてもいいです。

Set obj = …… で設定したオブジェクトに関して解放してあげてください。あと終了ボタン押した時の処理は Unload Meで終了しませんか? Endステートメントは避けた方がいいです。

あとまぁ切断ボタンを作らなくても、終了ボタンを押した一連の流れの中で切断処理を行えばいいかとは思います。

private Sub cmdEnd_Click()
a.close  ← ポートクローズ
unload me ← フォームのアンロード
End Sub

こんな感じで。まぁ、たぶんこれくらいのプログラムだと使ったからどうという訳でもないですが、他と連携するようなログラムになってくると思わぬ動作を引き起こす可能性もあります。

で、肝心の速度が遅い件ですが、どうやら切断する時に切断処理に時間がかかっているようですね。

と、いう事は具体的なコードがないと判断が難しいです。
接続-通信-切断を実際のコードでどのように処理しているのでしょうか。通信に関しては、もしかしてタイマーでくるくる回していますか?

その場合は先にタイマーを止めてみましょう。tmrObj.Enabled =False等。
後は具体的にコードをある程度書いていただかないと(一概にシリアル通信といっても、いろいろやり方があるので)、判断が難しいです。

投稿日時 - 2006-01-17 17:30:06

補足

ご回答を受けまして修正した部分は元に戻して記載します。なにぶん初心者ですので、ソースには不十分な部分が多いかと思います。よろしくお願いいたします。
------------------------------------------------------------
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

投稿日時 - 2006-01-17 19:32:21

ANo.4

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

投稿日時 - 2006-01-17 13:39:08

ANo.3

#1です。

通信プログラムの前提として
アプリ起動-接続-通信-切断-アプリ終了
というのは一連の流れとして、必ず実行しなくてはならない流れです。

ですので、切断せずにアプリを終了させようとすると通信を何とか続行しようとして時間がかかっている可能性がありますね。

ちなみにEndステートメントは強制的にプログラムを終了させるコマンドなので、あまり通常時に使用するのは望ましくないので使わない方が無難です。もっているオブジェクトを強制的に破棄するので、その時点でどのような動作をするかわからないからです。

どうしても必要な場合を除いて、開いているフォームを全てUnloadする事で終了させるようにした方が望ましいです。また何かオブジェクトや動的配列を使用していれば、そちらは解放(set obj = nothing や Erase a()等)してからUnloadする必要があります。

投稿日時 - 2006-01-17 13:37:54

補足

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

投稿日時 - 2006-01-17 16:29:45

ANo.2

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

投稿日時 - 2006-01-17 10:45:59

補足

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

投稿日時 - 2006-01-17 12:50:03

ANo.1

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

投稿日時 - 2006-01-16 21:07:28

補足

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

投稿日時 - 2006-01-16 22:10:51

あなたにオススメの質問