"refactor:Switch-serial-comm-to-polling"

This commit is contained in:
2025-12-18 00:34:37 +09:00
parent 51579591a2
commit 384f2affcb
13 changed files with 134 additions and 15 deletions

View File

@@ -207,7 +207,7 @@ namespace Project
//연결은 되었으나 통신이 지난지 10초가 지났다면 자동종료한다
var tsRecv = VAR.TIME.RUN(recvtime);
var tsConn = VAR.TIME.RUN(conntry);
if (tsRecv.TotalSeconds > 10 && tsConn.TotalSeconds > 5)
if (tsRecv.TotalSeconds > 30 && tsConn.TotalSeconds > 5)
{
this.BeginInvoke(new Action(() =>
{

View File

@@ -267,8 +267,12 @@ namespace arDev
nDataTemp = Convert.ToByte(rcvdNow.Substring(idx, 2), 16);
signal1.SetValue(nDataTemp); idx += 2;
if(idx < rcvdNow.Length-2)
{
nDataTemp = Convert.ToByte(rcvdNow.Substring(idx, 2), 16);
signal2.SetValue(nDataTemp);
}
DataReceive?.Invoke(this, new DataEventArgs(DataType.STS));

View File

@@ -51,6 +51,12 @@ namespace arDev
public string WriteErrorMessage = string.Empty;
public int WaitTimeout { get; set; } = 1000;
public int MinRecvLength { get; set; } = 1;
// Polling Thread related
protected Thread _recvThread;
protected volatile bool _isReading = false;
/// <summary>
/// 포트이름
/// </summary>
@@ -103,7 +109,7 @@ namespace arDev
_device = new System.IO.Ports.SerialPort();
this.BaudRate = 9600;
ScanInterval = 10;
_device.DataReceived += barcode_DataReceived;
// _device.DataReceived += barcode_DataReceived; // Removed event handler
_device.ErrorReceived += this.barcode_ErrorReceived;
_device.WriteTimeout = 3000;
_device.ReadTimeout = 3000;
@@ -147,9 +153,23 @@ namespace arDev
//
}
_device.DataReceived -= barcode_DataReceived;
// Stop reading thread
_isReading = false;
// _device.DataReceived -= barcode_DataReceived; // Removed event handler
_device.ErrorReceived -= this.barcode_ErrorReceived;
if (_recvThread != null && _recvThread.IsAlive)
{
_recvThread.Join(500);
}
if (_device != null)
{
if (_device.IsOpen) _device.Close();
_device.Dispose();
}
// Free any unmanaged objects here.
//
disposed = true;
@@ -158,9 +178,25 @@ namespace arDev
public Boolean Open()
{
try
{
if (_device.IsOpen == false)
{
_device.Open();
return IsOpen;
}
if (_device.IsOpen)
{
// Start polling thread
if (_isReading == false)
{
_isReading = true;
_recvThread = new Thread(ReadPort);
_recvThread.IsBackground = true;
_recvThread.Start();
}
return true;
}
return false;
}
catch (Exception ex)
{
@@ -193,6 +229,18 @@ namespace arDev
public virtual bool Close()
{
try
{
_isReading = false; // Stop thread loop
if (_recvThread != null && _recvThread.IsAlive)
{
if (!_recvThread.Join(500)) // Wait for thread to finish
{
// _recvThread.Abort(); // Avoid Abort if possible
}
}
if (_device != null && _device.IsOpen)
{
_device.DiscardInBuffer();
@@ -202,6 +250,11 @@ namespace arDev
}
else return false;
}
catch (Exception)
{
return false;
}
}
protected Boolean RaiseRecvData()
{
return RaiseRecvData(LastReceiveBuffer.ToArray(), false);
@@ -226,6 +279,9 @@ namespace arDev
try
{
// UI update might need Invoke if this event handler updates UI directly,
// but usually the subscriber handles Invoke.
// Since we are running on a background thread now, subscribers must be aware.
Message?.Invoke(this, new MessageEventArgs(Data, true)); //recvmessage
if (ProcessRecvData(Data) == false)
{
@@ -262,6 +318,9 @@ namespace arDev
}
byte[] buffer = new byte[] { };
// Replaced with ReadPort Loop
/*
void barcode_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
@@ -308,6 +367,62 @@ namespace arDev
}
}
*/
void ReadPort()
{
while (_isReading)
{
try
{
if (_device == null || !_device.IsOpen)
{
Thread.Sleep(100);
continue;
}
int readCount = _device.BytesToRead;
if (readCount > 0)
{
byte[] buffer = new byte[readCount];
_device.Read(buffer, 0, buffer.Length);
byte[] remainBuffer;
Repeat:
if (CustomParser(buffer, out remainBuffer))
{
//분석완료이므로 받은 데이터를 버퍼에 기록한다
if (LastReceiveBuffer == null || (LastReceiveBuffer.Length != tempBuffer.Count))
Array.Resize(ref LastReceiveBuffer, tempBuffer.Count);
Array.Copy(tempBuffer.ToArray(), LastReceiveBuffer, tempBuffer.Count);
tempBuffer.Clear();
//수신메세지발생
RaiseRecvData();
if (remainBuffer != null && remainBuffer.Length > 0)
{
//버퍼를 변경해서 다시 전송을 해준다.
buffer = new byte[remainBuffer.Length]; // Reallocate buffer for remaining data
Array.Copy(remainBuffer, buffer, remainBuffer.Length);
goto Repeat; //남은 버퍼가 있다면 진행을 해준다.
}
}
}
else
{
Thread.Sleep(20); // Data 없음, 대기
}
}
catch (Exception ex)
{
// Thread 상에서 Exception 발생 시 로그 남기고 계속 진행 여부 결정
// 여기서는 에러 메시지 발생시키고 Sleep
ErrorMessage = ex.Message;
this.Message?.Invoke(this, new MessageEventArgs(ex.Message, true));
Thread.Sleep(1000);
}
}
}
#endregion

Submodule Cs_HMI/SubProject/CommUtil updated: b070b711f0...ed05439991