여기 내 구현 방식은 비 차단, 동일한 스레드 솔루션입니다. 그것은 '\ r'과 '\ n'을 기다린 다음, 모든 버퍼링 된 문자를 파싱하기 위해 보내는 아주 기본적인 상태 기계입니다. 상태 기계 자체를 변경하여 원하는 줄 바꿈 값으로 변경할 수 있습니다. 이 접근 방식에서는 OnNewLineReceived 이벤트에 등록하고 SerialStringMessgae 이벤트 핸들러에서 데이터를 처리 할 수 있습니다. 시도/캐치 오버 헤드가 없습니다. 교착 상태는 없습니다.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace NonBlockingSerialPortReadLine
{
public partial class Form1 : Form
{
System.IO.Ports.SerialPort sp = new System.IO.Ports.SerialPort();
public event EventHandler OnNewLineReceived;
System.Windows.Forms.Timer NewDataTimer = new System.Windows.Forms.Timer();
int StateMachine = 0;
StringBuilder stringBuffer = new StringBuilder();
public Form1()
{
InitializeComponent();
InitTimer();
InitOnNewLineReceived();
}
private void InitTimer()
{
NewDataTimer.Interval = 50;
NewDataTimer.Tick += NewDataTimer_Tick;
}
private void InitOnNewLineReceived()
{
OnNewLineReceived += Form1_OnNewLineReceived;
}
void Form1_OnNewLineReceived(object sender, EventArgs e)
{
SerialStringMessgae STM = e as SerialStringMessgae;
string messgae = STM.message;
// PARSE YOU MESSAGE HERE - the debug line below is not mandatory
System.Diagnostics.Debug.WriteLine(messgae);
}
class SerialStringMessgae : EventArgs
{
public string message;
}
private void StartListeningButton_Click(object sender, EventArgs e)
{
StartListeningButton.Enabled = false;
sp = new System.IO.Ports.SerialPort("COM4",57600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One);
try
{
sp.Open();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return;
}
if (sp.IsOpen)
{
NewDataTimer.Enabled = true;
}
}
void NewDataTimer_Tick(object sender, EventArgs e)
{
string newData = sp.ReadExisting();
foreach (char c in newData)
{
switch (StateMachine)
{
case 0:
// waiting for '\r'
if (c == '\r')
{
StateMachine = 1;
}
else
{
stringBuffer.Append(c);
}
break;
case 1:
// waiting for '\n'
if (c == '\n')
{
if (OnNewLineReceived != null)
{
SerialStringMessgae STM = new SerialStringMessgae();
STM.message = stringBuffer.ToString();
OnNewLineReceived(this, STM);
}
}
// after parsing the message we reset the state machine
stringBuffer = new StringBuilder();
StateMachine = 0;
break;
}
}
}
}
}
나는 그것에 대해 생각하고 있었지만, 여러 사건이 발사 될까봐 걱정했다. 그 매우 귀중한 대답에 감사드립니다. – Kamil