/// <summary> /// 送信処理 /// </summary> protected void sendTask() { switch (sendStatus) { case SendStatus.Ready : /* 送信予約待ち */ // 送信データありの場合 if (sendQueue.Count > 0) { // コマンドを取り出す sendCommand = ((CommandStruct)sendQueue.Peek()).Clone(); isPolling = false; } // ポーリングタイムアウト発生 else if (isPolling) { sendCommand = new CommandStruct(); sendCommand.Cmd = 'R'; sendCommand.Address = 0x000A; sendCommand.size = 1; } // それ以外 else { return; } // リトライ回数を初期化 sendRetryCount = 0; sendStatus = SendStatus.Sending; break; case SendStatus.Sending : /* 送信中 */ // コマンドをバイト列に変換する byte[] cmd = sendCommand.Encode(); // コマンドを送信する。 try { write(cmd, 0, cmd.Length); sendTimer.Restart(); sendStatus = SendStatus.AckWaiting; } catch { ts.TraceInformation("Write処理失敗"); execSendRetry(); return; } break; case SendStatus.AckWaiting : /* Ack待ち */ // タイムアウト発生の場合はリトライ処理を行う。 if (sendTimer.ElapsedMilliseconds > timeout) { ts.TraceInformation("Ack待ちタイムアウトが発生"); execSendRetry(); return; } break; case SendStatus.CommandProcessing : /* コマンド実行 */ // 不正Ackの場合は、リトライを行う。 if (CommandUtil.CheckAckCommand(sendCommand, sendAckCommand) == false) { ts.TraceInformation("不正Ack受信"); execSendRetry(); return; } // Online状態でなければ、Onlineに切り替え if (status != Status.Online) { // 切断理由をリセットする comError = SystemConstants.COM_ERROR_NORMAL; // StatusをOnlineにする。 status = Status.Online; // 接続イベント発生 if (connstatusChange != null) { ConnStatusEventArgs e = new ConnStatusEventArgs(); e.EventCode = SystemConstants.EVENT_CONNECT; ctl.Invoke(connstatusChange, new object[] { this, e }); } } // コマンド実行 execCommand(sendAckCommand, sendCommand); // ポーリング通信の場合 if (isPolling) { // ポーリング状態の解除 isPolling = false; } // キューからのデータ指示の場合 else { // キューから1件データを削除する sendQueue.Dequeue(); } sendStatus = SendStatus.Ready; break; } }
/// <summary> /// 送信リトライ処理 /// </summary> protected void execSendRetry() { // リトライ回数内 if (sendRetryCount < SystemConstants.MAX_RETRY_COUNT) { status = Status.Suspended; sendStatus = SendStatus.Sending; ts.TraceInformation("リトライ{0}回目", new object[] { sendRetryCount + 1 }); sendRetryCount++; } // リトライ回数オーバー else { // 通信途絶 PortClose(); ts.TraceInformation("リトライ回数をオーバーしました。"); // 切断理由を変更 comError = SystemConstants.COM_ERROR_RETRYERROR; // 切断イベントの通知 if (connstatusChange != null) { ConnStatusEventArgs args = new ConnStatusEventArgs(); args.EventCode = SystemConstants.EVENT_DISCONNECT; ctl.Invoke(connstatusChange, new object[] {this, args}); ts.TraceInformation("切断イベントが発生しました。"); } } }