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

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

新規登録して質問してみよう
ただいま回答率
87.20%
Visual Studio

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

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

解決済

シリアル通信でマルチスレッド化(同時受信データを処理したい)

entaro12345
entaro12345

総合スコア51

Visual Studio

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

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

2回答

0評価

0クリップ

5773閲覧

投稿2020/09/15 03:02

前提・実現したいこと

以前も似たようなご質問をさせていただきましたが、再度質問させていただきます。
以前の質問

C#でUSB接続でシリアル通信を行うWindowsアプリを作成しています。
同時に複数のデータが来た場合に対応するために、マルチスレッドに変更したいと思っております。
が、恥ずかしながらマルチスレッドの実装を行ったことがなく、ググってもイマイチだったため、
皆さまのお力を借りたいと思いました。
現状は、データが2回来て正常なデータとするため、同時に来た場合にさばけない状態となっています。
(先勝ちな状態です。)

データの一連の流れは、下記になります。
①データ受信[1回目]
②データ受信[2回目] ← ここでデータ確定
③受信データをAPI経由でDBへ格納
④戻り値を受信元へ送信

該当のソースコード

C#

using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.IO.Ports; using System.Net.Http; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Xml.Linq; namespace App { public partial class Form : Form { private SerialPort serialPort; // APIパス private const string API_PATH = @"http://XXXXX"; private int iRetry = 1; private int iSeq = 0; private string sBefData = string.Empty; private string sData = string.Empty; private string sVal1 = string.Empty; private string[] sReturnVal = new string[2]; private bool bFirst = true; readonly string sPath = AppDomain.CurrentDomain.BaseDirectory; private string sFilePathBefore; string sLogFolder = "LogFile"; private bool bSuccess = false; public Form() { InitializeComponent(); } /// <summary> /// フォームロード時イベント /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form_Load(object sender, EventArgs e) { string[] ports = SerialPort.GetPortNames(); foreach (string port in ports) { this.cmbSerials.Items.Add(port); } if (0 < this.cmbSerials.Items.Count) { this.cmbSerials.SelectedIndex = 0; } } /// <summary> /// 接続ボタン押下時イベント /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnConnect_clicked(object sender, EventArgs e) { if (this.cmbSerials.SelectedItem != null && this.serialPort == null) { // COMポートをOPEN serialPort = new SerialPort(); serialPort.DataReceived += new SerialDataReceivedEventHandler(SerialPort1_DataReceived); serialPort.PortName = this.cmbSerials.SelectedItem.ToString(); serialPort.BaudRate = 19200; serialPort.DataBits = 8; serialPort.Parity = Parity.None; serialPort.StopBits = StopBits.One; serialPort.Encoding = Encoding.UTF8; try { serialPort.Open(); } catch (Exception ex) { } } } /// <summary> /// データ受信時イベント /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { if (serialPort != null && serialPort.IsOpen) { try { // 受信データを読み込む SerialPort sp = (SerialPort)sender; string sChildData = sp.ReadExisting(); if (sChildData.Length == 2 && bFisrst) { sVal1 = sChildData; } else { sData = sChildData; if (bFirst) { return; } } if (!string.IsNullOrEmpty(sData) && !string.IsNullOrEmpty(sVal1)) { if (0 < sData.Length) { if (string.IsNullOrEmpty(sBefData) || sBefData != sData) { var parameters = new Dictionary<string, string>() { // APIへ渡すデータセット }; var content = new FormUrlEncodedContent(parameters); try { sReturnVal = GetResponseAPI(API_PATH, content); sBefData = sData; bSuccess = true; } catch { bSuccess = false; } if (bSuccess) { if (0 < sReturnVal.Length) { try { // 送信元へデータ送信 } catch (Exception ex) { } } else { this.iRetry = 1; } } sData = string.Empty; sVal1 = string.Empty; sReturnVal = new string[]{ }; } } } } catch (Exception ex) { } } } /// <summary> /// 終了ボタン押下時イベント /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnFinish_clicked(object sender, EventArgs e) { if (serialPort != null && serialPort.IsOpen) { serialPort.Close(); serialPort = null; } } /// <summary> /// APIをたたいてレスポンスを取得 /// </summary> private string[] GetResponseAPI(string sApiUrl, FormUrlEncodedContent sContent) { string[] sVal = new string[2]; var task = Task.Run(() => { return HttpPost(sApiUrl, sContent); }); string response = task.Result; JArray data = (JArray)JsonConvert.DeserializeObject(response); foreach (JObject obj in data) { JValue did = (JValue)obj["device_id"]; JValue val = (JValue)obj["return_data"]; sVal[0] = (string)did.Value; sVal[1] = (string)val.Value; } return sVal; } /// <summary> /// APIをPOSTする /// </summary> /// <param name="sUrl">APIのURL</param> /// <param name="fContent">引数をエンコードしたもの</param> /// <returns></returns> async public Task<string> HttpPost(string sUrl, FormUrlEncodedContent fContent) { var client = new HttpClient(); var response = await client.PostAsync(sUrl, fContent); return await response.Content.ReadAsStringAsync(); } } }

補足情報(FW/ツールのバージョンなど)

Windows 10
Visual Studio 2017
c#/Windows Form/.Net Framewrok 4.7.1

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Visual Studio

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

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。