C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

メインフォームと通信フォームを別スレッドで実行させたい。 /ヒロカンサ (20/12/25(Fri) 16:03) #96625
Re[1]: メインフォームと通信フォームを別スレッドで実行させ.. /魔界の仮面弁士 (20/12/25(Fri) 16:43) #96626
Re[1]: メインフォームと通信フォームを別スレッドで実行させ.. /kiku (20/12/25(Fri) 18:14) #96627
  └ Re[2]: メインフォームと通信フォームを別スレッドで実行させ.. /ヒロカンサ (20/12/26(Sat) 17:17) #96631
    ├ Re[3]: メインフォームと通信フォームを別スレッドで実行させ.. /WebSurfer (20/12/28(Mon) 09:28) #96633
    └ Re[3]: メインフォームと通信フォームを別スレッドで実行させ.. /kiku (21/01/05(Tue) 15:50) #96652


親記事 / ▼[ 96626 ] ▼[ 96627 ]
■96625 / 親階層)  メインフォームと通信フォームを別スレッドで実行させたい。
□投稿者/ ヒロカンサ (1回)-(2020/12/25(Fri) 16:03:19)

分類:[VB.NET/VB2005 以降] 

開発環境:Win10 Home 64bit
使用言語:Visual Studio Community 2019

VB.net、初心者です。
Visual Basic にて、メインフォームとシリアル通信をしている
フォームがあります。
メインフォームでは、シリアル通信で取得したデータを
使って処理を行っています。
メインフォームで処理をしていると、シリアル通信の処理が
止まってしまいます。
同時に並行処理を行いたいので、別スレッドでシリアル通信を
実行させたいのですが、方法がわかりません。
Webでの情報をもとに、

Dim t As New System.Threading.Thread( _
New System.Threading.ThreadStart(AddressOf frmSerial.show))
'スレッドを開始する
t.Start()

と記述してみたのですが、直ぐにフォームが閉じてしまいます。

非常に困っています、どうかご教授下さい。


[ □ Tree ] 返信 編集キー/

▲[ 96625 ] / 返信無し
■96626 / 1階層)  Re[1]: メインフォームと通信フォームを別スレッドで実行させたい。
□投稿者/ 魔界の仮面弁士 (2943回)-(2020/12/25(Fri) 16:43:43)
No96625 (ヒロカンサ さん) に返信
> 同時に並行処理を行いたいので、別スレッドでシリアル通信を
> 実行させたいのですが、方法がわかりません。

何もしなくても、シリアル通信は別スレッドで行われます。
そして、フォーム側の UI スレッドと、シリアル通信のスレッドを共有することはできません。

DataReceived イベントのタイミングで、Invoke / BeginInvoke メソッドを呼び出せば、
通信スレッドで得たデータを UI スレッドに渡して、UI スレッド側に処理させることができます。
https://www.atmarkit.co.jp/ait/articles/0506/17/news111.html


通信頻度と画面への更新タイミングに差異があるようなケースでは、
受信した通信データを、外部ファイルもしくはスレッドセーフなコレクション等に蓄えておき、
画面側はそれを、タイマーあるいは変更通知を受けて読み取るようにするという手法もあります。


> Visual Basic にて、メインフォームとシリアル通信をしている
> フォームがあります。

メインフォームは分かりますが、通信フォームというのは何者ですか?
受信した内容を表示するだけなら、メインフォームと通信フォームは
同一のスレッドのままで良いと思いますよ。

技術的には、メインフォームと通信フォームを別スレッドで実行させる事は可能ですが、
その場合、それぞれの UI スレッドごとに、個別のメッセージループを回す必要がありますし、
フォーム間の直接連携もできなくなるので、ますますややこしくなってしまいます。
[ 親 96625 / □ Tree ] 返信 編集キー/

▲[ 96625 ] / ▼[ 96631 ]
■96627 / 1階層)  Re[1]: メインフォームと通信フォームを別スレッドで実行させたい。
□投稿者/ kiku (214回)-(2020/12/25(Fri) 18:14:25)
No96625 (ヒロカンサ さん) に返信
> 開発環境:Win10 Home 64bit
> 使用言語:Visual Studio Community 2019
>
> VB.net、初心者です。
> Visual Basic にて、メインフォームとシリアル通信をしている
> フォームがあります。
> メインフォームでは、シリアル通信で取得したデータを
> 使って処理を行っています。

シリアル通信をしているフォームは、
通信をしていること以外に何をしていますか?

通信開始ボタンがあるとか?
何か表示しているとか?

[ 親 96625 / □ Tree ] 返信 編集キー/

▲[ 96627 ] / ▼[ 96633 ] ▼[ 96652 ]
■96631 / 2階層)  Re[2]: メインフォームと通信フォームを別スレッドで実行させたい。
□投稿者/ ヒロカンサ (2回)-(2020/12/26(Sat) 17:17:43)
No96627 (kiku さん) に返信
> ■No96625 (ヒロカンサ さん) に返信
>>開発環境:Win10 Home 64bit
>>使用言語:Visual Studio Community 2019
>>
>>VB.net、初心者です。
>>Visual Basic にて、メインフォームとシリアル通信をしている
>>フォームがあります。
>>メインフォームでは、シリアル通信で取得したデータを
>>使って処理を行っています。
>
> シリアル通信をしているフォームは、
> 通信をしていること以外に何をしていますか?
>
> 通信開始ボタンがあるとか?
> 何か表示しているとか?
>

シリアル通信は、フォームのロードイベントで

タイマーコントロールを張り付けて、0.1秒間隔で、データの送受信を行うようにしています。

シリアル通信でやり取りしているデータを、表示しています。(通信のモニタ)

メインフォームでは、ファイルの読み書きや一時待ちのthread.sleep とか、行っています。

その間もシリアル通信を止めたくないので、どうかご教授ください。

VB.net初心者で、魔界の仮面弁士さんからもアドバイス頂いていますが、内容が、理解できていません。

すいません、よろしくお願いします。



[ 親 96625 / □ Tree ] 返信 編集キー/

▲[ 96631 ] / 返信無し
■96633 / 3階層)  Re[3]: メインフォームと通信フォームを別スレッドで実行させたい。
□投稿者/ WebSurfer (2174回)-(2020/12/28(Mon) 09:28:33)
No96631 (ヒロカンサ さん) に返信

> シリアル通信は、フォームのロードイベントで
>
> タイマーコントロールを張り付けて、0.1秒間隔で、データの送受信を行うようにしています。

「c# シリアル通信 非同期」などをキーワードのググると役に立ちそうな記事が
いろいろヒットしますがやってみましたか? 例えば下記:

C#Taskクラスを使ってシリアル通信の非同期処理
https://tomosoft.jp/design/?p=11200

上の記事では btnconnect_Click で非同期に受信を行っているようですが、質問
者さんのケースではそこのところを Timer のイベントにするとかで質問者さんの
やりたいことができないか検討されてはいかが?

他にもググればいろいろヒットすると思いますのでやってみましょう。
[ 親 96625 / □ Tree ] 返信 編集キー/

▲[ 96631 ] / 返信無し
■96652 / 3階層)  Re[3]: メインフォームと通信フォームを別スレッドで実行させたい。
□投稿者/ kiku (215回)-(2021/01/05(Tue) 15:50:55)
No96631 (ヒロカンサ さん) に返信
> シリアル通信は、フォームのロードイベントで
> タイマーコントロールを張り付けて、0.1秒間隔で、データの送受信を行うようにしています。
> シリアル通信でやり取りしているデータを、表示しています。(通信のモニタ)
> メインフォームでは、ファイルの読み書きや一時待ちのthread.sleep とか、行っています。
> その間もシリアル通信を止めたくないので、どうかご教授ください。
> VB.net初心者で、魔界の仮面弁士さんからもアドバイス頂いていますが、内容が、理解できていません。

C#なら具体的なコードを書いても良かったんですが、
VB.NETは苦手なので、方向性のみです。
現在、通信フォームでは送受信データを表示する機能のみで
その他の機能がないようなので、
実装を簡単にするため、メインフォームでシリアル通信を行い、
その送受信データのみを、通信フォームに知らせる方式が良いと思います。

非同期を使った別の実装方法もありますが、
すでにWindowsタイマを使って送受信しているようなので
あえてそのまま活かした提案をしています。
URLはたぶんわからないかもしれない部分に参考として貼ってあります。

a)メインフォーム
・メインフォーム起動時に、通信フォームをモードレスとして表示。
 https://dobon.net/vb/dotnet/form/showform.html
・フォームタイマで定期的にシリアルポートから受信。
 たぶん、もうやり方はわかっているはず。
・受信したら、通信フォームのメッセージ登録メソッドでメッセージ登録
 ※例えばこんな読み出し方
 通信フォーム.setMessage("受信内容")
 https://dobon.net/vb/dotnet/form/accessanotherformdata.html
・受信したら、ファイルへの書き出しなどを行う。
・メインフォーム終了時に、通信フォームを閉じる。

b)通信フォーム
定期的にメインフォームからの情報を表示。
・メッセージ登録メソッドを作成し、公開する。
 メッセージをキューに登録する。
 ※キューへの排他は必要
・フォームタイマで定期的にキューから取り出す。
 ※キューへの排他は必要
 https://www.atmarkit.co.jp/ait/articles/1801/31/news023.html

[ 親 96625 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -