質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

スレッドセーフ

マルチスレッド環境において、複数のスレッド上で常に正常に実行する事が可能なコードを、スレッドセーフなコードと呼びます。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

1回答

2413閲覧

連続送信データ処理時のメインフォーム操作不可能について

abanda

総合スコア12

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

スレッドセーフ

マルチスレッド環境において、複数のスレッド上で常に正常に実行する事が可能なコードを、スレッドセーフなコードと呼びます。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2017/03/13 14:06

いつもお世話になっております。
今回の質問はデータを連続で送信している際にメインフォームが操作できなく現象についてです。

現象の再現方法
1,TCP_TEST_FORM_APPRI_SERVERのメインフォームからServerFormを二つ以上立ち上げる。
2.TCP_TEST_FORM_APPRI_CLIENTを立ち上げて二つ以上接続する。
3,TCP_TEST_FORM_APPRI_SERVER側で設定画面から連続送信チェックボタンにチェックをする。
4,TCP_TEST_FORM_APPRI_CLIENT側で何らかの文字をサーバーに送る。
5,TCP_TEST_FORM_APPRI_SERVERのメインフォームが操作できず、サーバー側からデータが送られ続ける状態となる。

やりたい事はある特定の文字がきたらサーバー側が文字を連続で返すようにしたく、連続送信をサーバー側で止める事のできる形にしたいのです。
連続送信時はクライアント側からデータが受け取れる状態にもしたいと考えています。(クライアント側からも停止文字を送りたい為。)

フォームの操作ができなくなるとは考えいなかったので、困っています。
これはスレッドの重複によるものなのか、それともループのしすぎでほかの処理ができなくなっているのか、どなたかわかる方がいらっしゃればご教授をお願いします。

前回と同様にProjectをアップロード致しますので、お手数をかけますがDLしてソースを見てもらえればと思います。
リンク内容:DLパス 今年の西暦4桁を数字で

VB.net

1 Private Sub ContinuousSendMethod(ByVal sendData As String) 2 3 Try 4 Do 5 If setting.NoContinueCheck.Checked Then 6 Exit Do 7 End If 8 '送信文字一覧に書き込む 9 RaiseEvent WriteSendData(sendData) 10 11 '送られてきたデータの判定をクライアント側に送信 12 SendCode(sendData) 13 Loop 14 Catch ex As Exception 15 RaiseEvent WriteLog("連続送信時エラー " + ex.ToString()) 16 Return 17 End Try 18 End Sub

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

連続送信のループに処理が取られ過ぎて、他の処理が動けていないみたいです。

下記のようにループ内にウエイトを入れて、他の処理を実行する余裕を作りましょう。

VB.NET

1 Private Sub ContinuousSendMethod(ByVal sendData As String) 2 3 Try 4 Do 5 6 If setting.NoContinueCheck.Checked Then 7 Exit Do 8 End If 9 10 '送信文字一覧に書き込む 11 RaiseEvent WriteSendData(sendData) 12 13 '送られてきたデータの判定をクライアント側に送信(このメソッド内で呼ばれた場合は受信データは常に同じ 別スレッドで判定され、測定終了となる。) 14 SendCode(sendData) 15 16 'CPUを逃がす 17 Threading.Thread.Sleep(0) 18 Loop 19 Catch ex As Exception 20 RaiseEvent WriteLog("連続送信時エラー " + ex.ToString()) 21 Return 22 End Try 23 End Sub 24

現状ですと、クライアントからデータが送信されるたびに、連続送信用のスレッドが開始されます。
この為、クライアント側の受信処理でも負荷が上がり操作が利きにくくなっていきます。
ですので、ここら辺も考慮したプロトコルを設計する必要があると思います。


また、以前指摘したようにTCPクラスからフォームのコントロールをアクセスすべきではありません。
(今回はsetting.NoContinueCheck.Checked)
今後、クライアントからの送信データでも連続送信を停止したいとのことですから、
連続送信を行うかどうかのプロパティを用意し、連続送信処理でそのプロパティを見るとしたほうが良いと思います。

VB.NET

1 ''' <summary> 2 ''' 連続送信を行うかどうかを設定、取得する。 3 ''' </summary> 4 ''' <returns>False:連続送信しない True:連続送信する</returns> 5 Public Property ContinuousSend As Boolean 6 7 8 9 ' 10 ' 受信処理内 11 ' 12 '受信文字一覧に書き込み依頼 13 RaiseEvent WriteRecivedData(resMsg) 14 15 If resMsg = "連続送信停止" Then 16 ContinuousSend = False 17 End If 18 If ContinuousSend Then 19 '連続送信用スレッド 20 Dim continuousSend As Thread = New Thread(New ParameterizedThreadStart(AddressOf ContinuousSendMethod)) 21 continuousSend.Start(resMsg) 22 Else 23 '送られてきたデータを判定し、送信データの作成及びデータの送信処理 24 SendCode(resMsg) 25 End If 26 27 RaiseEvent WriteSendData(resMsg) 28 29 30 31 32 33 34 ''' <summary> 35 ''' 連続送信用メソッド 36 ''' </summary> 37 ''' <param name="sendData">送信データ</param> 38 ''' <remarks>メインスレッド、通信スレッドでもなく、3つ目のスレッド</remarks> 39 Private Sub ContinuousSendMethod(ByVal sendData As String) 40 41 Try 42 While ContinuousSend 43 44 '送信文字一覧に書き込む 45 RaiseEvent WriteSendData(sendData) 46 47 '送られてきたデータの判定をクライアント側に送信(このメソッド内で呼ばれた場合は受信データは常に同じ 別スレッドで判定され、測定終了となる。) 48 SendCode(sendData) 49 50 Threading.Thread.Sleep(0) 51 End While 52 53 Catch ex As Exception 54 RaiseEvent WriteLog("連続送信時エラー " + ex.ToString()) 55 Return 56 End Try 57 End Sub 58

投稿2017/03/13 15:05

編集2017/03/13 15:53
YAmaGNZ

総合スコア10222

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

abanda

2017/03/14 14:11

たびたびの質問に回答してくださりありがとうございます。 ループ処理のせいで他の操作ができなくなっていたのですね。原因は分かってもうまく改善するのは難しそうです。設定値を共通化せずに、多重起動で設定値を個別で設定する方針を取ろうかなと思います。クライアント側も重くなっているとは気づきませんでした。こういった事が起こらないようにプロトコルが大事なのですね、また勉強になりました。 外部からのフォームコントロールアクセスに関しては気を付けようと思っていたのですが、ついついやってしまいがちになっています。良い設計を心掛けたいのでこれからはもっと注意するようにします。 丁寧な解説でいつも勉強になり、感謝しております。それではありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問