C#×RS-232C通信の振り返りと非同期処理についてさん3 日前読了時間: 3分はじめにこんにちは!【さん】です。今回ブログを書くにあたり、数年前に開発した計測機器の検査ソフトのコードを読み返し、その時のことを備忘録として残そうと思います。入社間もない頃、「RS-232C(シリアル通信)」という、弊社では最近触れる機会が少なくなった通信規格と格闘していました 。改めて当時を振り返ると、泥臭く安定化させた「過去の実装」と、今だからこそ見える「これからの課題」が浮き彫りになってきました。過去の自分が行った「通信安定化」の工夫RS-232Cは、モダンな通信規格に比べると非常にシンプルですが、その分「データの受け取り方」に一工夫必要です。 私が実装の中で特に意識した、安定化のためのポイントを紹介します。1. 受信完了まで「粘り強く待つ」リトライ構造シリアル通信では、一度の読み込みで全てのデータが取得できるとは限りません。 そのため、受信バッファが空だったとしてもすぐに処理を諦めず、わずかな待機時間を設けて再確認する構造にしました 。2. 徹底したバッファ管理シリアル通信のバッファには、ノイズや前回通信の読み残しが「ゴミ」として残ってしまうことがあります。 これが原因で解析エラーが起きるのを防ぐため、コマンド送受信の前後でバッファを強制的にクリア(破棄)する処理を挟んでいます 。3. デリミタ(区切り文字)による正確な切り出しデータが垂れ流しで届くシリアル通信では、「どこまでが一つの命令か」を判断する目印が不可欠です。 今回は CR(キャリッジリターン)を区切りとして、1文字ずつバッファに貯めていき、デリミタが来たタイミングで解析を開始するロジックを採用しました 。今だからこそ見える「これからの課題」当時の工夫は「動くものを作る」ためには正解でしたが、現在の視点で読み返すと、通信中の「待ち時間」の扱いに大きな課題を感じます。待ち時間の代償先ほど紹介したリトライ構造では、データが届くまで Thread.Sleep(30) でスレッドを完全に止めて待機していました 。30ミリ秒というのは、最新のCPUにとっては数百万サイクル分もの膨大な時間です 。この間、スレッドはただ占有されている状態で、UIスレッドであれば画面がフリーズしてしまいます 。非同期処理(async/await)への昇華今後このシステムをリプレースするなら、最も手を入れたいのはこの「待機中のリソース解放」です 。・Task.Delay への置き換え Thread.Sleep を await Task.Delay に置き換えることで、待機中もスレッドを解放し、画面更新などの他の処理に回すことができます 。・「古い技術」を「現代の作法」で包む リトライ構造の重要性は変わりませんが、それを非同期にすることで、ユーザーは「検査中」という表示を見ながら別の操作を続けることが可能になります 。「古いデバイスと通信しているから、ソフトも古いままでいい」のではなく、待ち時間が長い通信だからこそ、最新の非同期処理で効率化する恩恵が最大化されるのだと確信しています 。おわりにあまり触れることのないRS-232Cでしたが、その「不自由さ」を制御する工夫は、通信プログラムの基本を再確認する良いきっかけになりました 。 過去の自分を今の自分がアップデートしていくような感覚を大切にしながら、基本の工夫と新しい技術の両方を、これからの開発に活かしていきたいです。
コメント