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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

3回答

4241閲覧

C# 定時間ごとに送信するシリアル通信をasync/awaitを使って実装したい

luckyclock

総合スコア73

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

1クリップ

投稿2019/01/17 08:51

シリアル通信で相手にコマンド送信して応答があったらまたコマン
ドを送信するというのを無限に繰り返す。
コマンドを送って200ms応答がなかったら、またコマンドを送る
(相手機器が復帰することを考えて応答がなくても定期的にコマンドを送る)
という処理を考えた時、非同期処理で作る場合どのように作るのが
ベターでしょうか?
async/awaitを使って実装できますでしょうか?
そもそもasync/awaitを使った方法でいいのでしょうか。
どのようなコードを書いたらいいのかわからないでいます。

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

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

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

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

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

guest

回答3

0

まずは、普通にそういう動作をするコードを関数にまとめて書いてみましょう。
あとはそれを別スレッドで実行するようにするだけです

投稿2019/01/17 08:58

y_waiwai

総合スコア87749

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

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

luckyclock

2019/01/17 09:24

わからないなりに書きました。 問題点 200ms立った時rxFlg=faulse;にしないといけないですが200ms応答がなかったというのを どこで処理するのか。 受信が非同期になってない気がする。 private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { String str = serialPort1.ReadLine(); rxFlg = true; Console.Write(str); } private async void tx() { while (true) { await Task.Run(() => { if (rxFlg == false) { serialPort1.Write("コマンド\r\n"); Task.Delay(200); } }); } }
luckyclock

2019/01/17 09:34

200ms応答がないというはどうやってカウントすればいいですか?
y_waiwai

2019/01/19 07:32

DataReceivedイベントは使用しないで、SerialPortのRcvTimeoutを200msにしといてDelayの代わりに使うというのはどうでしょう。 ReadLineの戻り値で応答があったかどうかは判定できます
hillacken

2019/01/22 04:33

SerialPort.ReadTimeoutに200をセットする案に賛成です。 自分ならそうします。 serialPort1.Write("コマンド\r\n"); String str = serialPort1.ReadLine(); とやれば 200ms応答が無ければTimeoutExceptionになります。
guest

0

async/awaitを使って実装できますでしょうか?

出来ます。

そもそもasync/awaitを使った方法でいいのでしょうか。

それは設計思想なので良し悪しはありません。
Taskを使う場合は、随時Taskを生成し応答を貰う。
自前のスレッドを使う場合は、処理のスプーラーを用意してそのスプーラーに処理を追加する。自前のスレッドはスプーラーに処理があれば逐次処理をする。

いずれにせよ同期処理が出来なければ、非同期処理はできません。
同期処理を非同期にするのはそんなに難しくはありません。

投稿2019/01/17 09:17

hihijiji

総合スコア4150

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

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

0

200ms応答がないというはどうやってカウントすればいいですか?

例えばコマンドを送信した直後に200ms秒後に発火するタイマーを開始させます。

タイマーの発火よりserialPort1_DataReceivedが早ければ
タイマーを止めて受信処理をすれば良いですし、

serialPort1_DataReceivedよりタイマーの発火が早ければ、
コマンドを再送信すれば良いでしょう。
(こちらのケースでタイマーを停止→再開するかはお好み)

投稿2019/01/18 06:36

takabosoft

総合スコア8356

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問