• 締切済み

VB2005 シリアル通信のClose処理

いつもお世話になっております。 表題の件につきまして、ご教示ください。 【処理内容】 メインフォームのボタンからポートをオープンし、 受信データ(1Byte)をテキストボックスに表示し続ける。 ※受信データは定期受信 通信をやめたいときにメインフォームのボタンから ポートをクローズする。 上記、クローズ時に、ほぼフリーズします。 原因はシリアル通信の受信イベントが別スレッドにて処理されているため、 Invoke()にてテキストボックスの更新をしており、 これが悪さをしているみたいです。 BeginInvoke()を使用するとフリーズは回避することができるのですが、 テキストボックスに表示される受信データの内容が激しく欠落してしまいます。 Invoke()を使いつつ、フリーズを回避する方法はないのでしょうか。 無知で大変申し訳ございませんが、よろしくお願いいたします。

みんなの回答

  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.1

この方法が最善とは思いません 一例として >クローズ時に、ほぼフリーズします。 フリーズとはPCが固まるフリーズではなくて アプリがエラー出してすっ飛ぶんですよね(多分) それとも飛びもせずプロセス残ったまま反応しなくなるのでしょうか? 以下は すっ飛んでるんだろうと仮定して書いています メイン(ボタン)処理で ・クローズ前に スレッドに対して終了要求フラグを立てる ・スレッドが終了するまで待つ(フラグでもシグナルでも確認はいくつか考えられます) ・ポートクローズ処理を行う ・スレッドでは終了フラグを監視して動作(現状多分ポーリングループしてるんでしょう)  するように変更する ・スレッド終了フラグを立てる といった形でいいのでは? もしくは実質のオープン・クロース処理自体をスレッド内に記載してもいいかと メイン側処理とスレッド側処理で同期取れればどんな形でもいいかと思います 同期が取れてないからタイミングによってクローズ後にデータ読みに行って アプリがすっ飛ぶということではないかと思います テキストボックスの更新自体が問題の本質ではないと思いますよ (データ読みに行って更新されるからこそ表示してるんでは?)

関連するQ&A

  • VB2010で、シリアル通信の方法を教えてください。

    VB2010で、シリアル通信の方法を教えてください。 ツールボックスの「Serial Port」を使っています。 送信までは難なくできたのですが、受信が旨くいきません。 参考にしたサイトは、 http://msdn.microsoft.com/ja-jp/library/cc720852.aspx です。 これを実行すると、受信が出来ないだけでなく、フリーズしてしまいます。 どうやったら、受信できるのでしょうか?

  • C#でメッセンジャー作ってますがテキスト通信について。

    今C#でメッセンジャーを作っているのですが テキストでのチャット部分について分からないので質問させてください! 複数の人と同時にTCPでチャットを出来るようにしたいです。 そこでまず1対1で通信できるプログラムを作ろうと思ったのですが 複数の人とチャットするために新しいフォームを作ったとき同じポートとIPアドレスで通信しようとして接続できませんよね? 自分ではメインのフォームで一括してデータを受信して対応するフォームにデータを割り振るのが良いかな? って思ったのですがこれもまたどのようにして受信したデータを対応したフォームに割り振れば良いのか分からず困っています。 この問題をどのように回避するのが良いでしょうか?

  • シリアル通信の方法(VB)

    VisualBasicを使ってシリアル通信(受信のみ)を考えている初心者です。 現在、フォームのデザイナーからSerialportをドラッグしプロパティを設定しました。 コードでは、ポートを開き、受信の命令をしていますが ".readline"の文のところでフリーズしてしまいます。 ---------- SerialPort1.Open() Dim receivedata As String = "" receivedata = SerialPort1.Readline ---------- 原因がつかめず困っています。 何がいけないのでしょうか?詳しい方、是非ご教授お願いします。

  • visual c# 2010 シリアル通信アプリ

    http://www.kana-soft.com/tech/sample_0007.htm のサイトを参考に、マイコンとのシリアル通信評価に使うPCのアプリケーションを visual c# 2010で作っています。 一応データを受け取るようになったのですが、 63H 62H 61H 00H (アスキーコードだと"cba<null>") というデータを送っているはずなのですが、 扣a というデータが受信されてしまいます。 正しく受信するにはどうすれば良いでしょうか。 (該当していそうな部分のソースです) : : /****************************************************************************/ /*! * @brief データ受信が発生したときのイベント処理. * * @param [in] sender イベントの送信元のオブジェクト. * @param [in] e イベント情報. * * @retval なし. */ private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { //! シリアルポートをオープンしていない場合、処理を行わない. if (serialPort1.IsOpen == false) { return; } try { //! 受信データを読み込む. string data = serialPort1.ReadExisting(); //! 受信したデータをテキストボックスに書き込む. Invoke(new Delegate_RcvDataToTextBox(RcvDataToTextBox), new Object[] { data }); } catch (Exception ex) { MessageBox.Show(ex.Message); } } /****************************************************************************/ /*! * @brief 受信データをテキストボックスに書き込む. * * @param [in] data 受信した文字列. * * @retval なし. */ private void RcvDataToTextBox(string data) { //! 受信データをテキストボックスの最後に追記する. if (data != null) { rcvTextBox.AppendText(data); } }

  • VB2005 で複数チャンネルのシリアル通信処理

    初めて投稿します、VB2005への初心者です。 複数ポートでシリアル通信を同時に送受信を行おうといているのですが 旨く出来ません。 comm1をOPENして受信を行うとcomm2の受信が行えなくなります。 逆にcomm2から行っても最初にOPENしたcomm1側の受信処理が行えなくなってしまいます。 複数のcommを使用しての処理はどのようにしているのかご教授お願いします。

  • シリアル受信データをファイルに書き出したい

    マイコンとPCをCOMポートで通信し、受信データをファイルに書き出したいのです。 やってみたこと1.と2.の間を埋める技術についてアドバイスをお願いします。 1.キーボード入力したテキストボックスの内容をファイルに書き出す ⇒書けました、OK     Dim xxx As New System.IO.StreamWriter("e:xxx.txt", False, System.Text.Encoding.Default) xxx.WriteLine(TextBox1.Text) xxx.Close() 2.サンプルコードでシリアル通信 ⇒受信データがテキストボックスに表示されました、OK     以下サイトを参考に勉強中、テキストボックス部分を抜粋させて頂きます     (http://www.kana-soft.com/tech/sample_0008_4.htm#1) 3.2.で表示されたテキストボックスの内容を、1.のように書き出したいのですが   上手くいきません。'■から'■間に xxx.WriteLine(RcvTextBox.Text) 書いてみましたが   e:xxx.txtは作成されません。delegate、invokeの理解不足が原因かと思うのですが、   調べ回るうちに・・・限界みたいです。(^_^;) (抜粋) '===== Private Delegate Sub Delegate_RcvDataToTextBox( data As String ) '===== Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived Try '受信データを読み込む. Dim data As String data = SerialPort1.ReadExisting() '受信したデータをテキストボックスに書き込む. Dim args(0) As Object args(0) = data Invoke(New Delegate_RcvDataToTextBox(AddressOf Me.RcvDataToTextBox), args) Catch ex As Exception MsgBox( ex.Message ) End Try End Sub '===== Private Sub RcvDataToTextBox( data As String ) '受信データをテキストボックスの最後に追記する. If IsNothing( data ) = False Then RcvTextBox.AppendText( data ) End If '■     Dim xxx As New System.IO.StreamWriter("e:xxx.txt", False, System.Text.Encoding.Default) xxx.WriteLine(RcvTextBox.Text) xxx.Close()     '■ End Sub ===== 以上、駄目出しをよろしくお願いします。

  • VBについて

    Visual Basicで1つのオブジェクトの中にフォームを2つ作った時、片方のフォームに入力した情報を処理し、もう1つのフォームでその結果を見るにはどうすれば良いのでしょうか?  例えば、1つのフォームにテキストボックスAとコマンドボタンを貼り付け、もうひとつにテキストボックスBを貼り付けて、テキストボックスAにXと入力し、コマンドボタンを押すとテキストボックスBにYと入力されるような事です。  分かる方、是非教えてください。

  • シリアル通信のイベント受信について

    現在VB6.0を使用してシリアル通信のプログラムを MsCommを使用せず、CreateFileを使用して行っておりますが、 データの受信を受信したタイミングでテキストボックスに表示したいのですが どの様にすると受信したタイミングでデータを取得できるのかわからず困っております。

  • VB RS-232C 通信プログラム

    何度もお世話になっております。(VB6.0 MSCommを使用した通信プログラムを作成中です。)私は新卒で食品会社に入社したのですが,プログラムの分かる上司が身近では誰1人といない状況で困っています。 今作成しているのは,重量計に荷物が乗った段階で作業者がデータ転送ボタン(重量計についている)を押すと,重量計のデータ(500kgというデータ)をシリアルでCOM1に取り込み,フォームにエクセルのセルを作成し(OLEを用いて)保存できるようにしたいと考えています。 (重量計から送られてくるデータのフォーマット) 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 S T , N T , + 0 0 1 2 . 3 4 k g CR LF ST ; ヘッダ1 NT ; ヘッダ2  CRLF ; ターミネータ                   の18バイトのデータです。 ここで質問なのですが (1) 以下のプログラムで重量はバイト配列に受信できていますでしょうか?(実際に重量計とPCを接続できれば良いのですが工場の稼動状況が関わっておりすぐにはできません。) (2) 18バイトのデータを受信するからと言って RThreshold = 18 として良いのでしょうか? 普通,データは1バイトずつ送られてくると思うので RThreshold = 1としてイベントを発生させる必要があるのかとも思うんですが。 'MSComm1,2(COM1,2)コントロールの初期設定 Private Sub Form_Load() MSComm1.CommPort = 1 '通信ポートを設定 MSComm1.Settings = "9600,n,8,1" '通信条件の設定 MSComm1.RThreshold = 18 '固定長のデータ End Sub Private Sub Port1_Click() 'Port1_Clickのクリックイベントプロシージャ If MSComm1.PortOpen = False Then 'シリアルポートのオープン MSComm1.PortOpen = True End If LPort1.Text = "" 'テキストボックスのクリア受信 End Sub Private Sub MSComm1_OnComm() '受信のOnCommイベント Dim Buffer1(0 To 17) As Byte '受信バッファの変数宣言(18バイト) Select Case MSComm1.CommEvent 'CommEventプロパティに対する処理 Case comEvReceive '受信データ有り    Buffer1 = MSComm1.Input '受信データをバッファに格納 'これより下は受信した18バイトから必要なデータ8バイト目から4バイト分切り出し,dという配列(4バイト)に格納できないかと考えました。 Dim i As Integer Dim d(0 To 3) As Byte d = MidB(Buffer1, 8, 4) LPort1.Text = d 'LPort1.Text = Buffer1 '受信データをテキストボックスに表示 End Sub

  • VBのMSCommコントロールを使ってシリアル通信をしています。

    VBのMSCommコントロールを使ってシリアル通信をしています。 データ受信時、90byteを超えたあたりで"??"(ASCIIコードで0x3Fが2回)が 挿入されたように受信されてしまいます。 前後のデータ関係をみると、2byteがデータ化けを起こしているわけでは なく、"??"が間に挿入されたような形です。 "??"が挿入される位置も受信の度に違います。 もしこのような現象の理由がわかる方がいらっしゃいましたら 回避策をお教えください。 <詳細設定> 38.4kbps、データ長:7、パリティ:Even、Stop bit :1 の設定。 http://www.compass-lab.com/STK_CAN/USB_Serial/USB_COMi.htm にあるUSB-comiでシリアルポートを追加してRS422変換しています。 データ長129byteのデータが250ms周期で送られてくるのを 読み取ろうとしています。

専門家に質問してみよう