직렬 포트 (예 : COM1)에서 데이터를 지속적으로 읽어야하는 일부 SerialPort 코드가 있습니다. 그러나 이것은 매우 CPU 집중적 인 것으로 보이며 사용자가 창을 이동하거나 많은 데이터가 창에 표시되는 경우 (예 : 직렬 회선을 통해 수신되는 바이트) 통신이 엉망이됩니다.System.IO.Ports.SerialPort 및 Multithreading
다음 코드를 고려 : 데이터 스트림 상수 및 데이터 (프레임/패킷)이 분석되어야로
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] buffer = new byte[port.ReadBufferSize];
var count = 0;
try
{
count = port.Read(buffer, 0, buffer.Length);
}
catch (Exception ex)
{
Console.Write(ex.ToString());
}
if (count == 0)
return;
//Pass the data to the IDataCollector, if response != null an entire frame has been received
var response = collector.Collect(buffer.GetSubByteArray(0, count));
if (response != null)
{
this.OnDataReceived(response);
}
코드를 수집 할 필요가있다.
port = new SerialPort();
//Port configuration code here...
this.collector = dataCollector;
//Event handlers
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
가 사용자 상호 작용이없고 아무 것도 창에 추가되고 있지 않으면 이 잘 작동하지만, 곧 상호 작용 통신이 있으므로 정말 엉망 가져옵니다.
Dispatcher.BeginInvoke(new Action(() =>
{
var builder = new StringBuilder();
foreach (var r in data)
{
builder.AppendFormat("0x{0:X} ", r);
}
builder.Append("\n\n");
txtHexDump.AppendText(builder.ToString());
txtHexDump.ScrollToEnd();
}),System.Windows.Threading.DispatcherPriority.ContextIdle);
});
을하지만, 심지어 간단한 통화는 문제를 일으킬 log4net하기 : 제한 시간은 예를 들어
.... 등이 발생,이 모든 것을 망쳐 놨어요.
이 경우 위는하지 않았다 많은 sence : ...
업데이트
는하여 SerialPort 통신 을 최적화 할 수있는 모범 사례가 있습니까 또는 누군가가 내가 잘못 뭘하는지 말해 줄 수 .
class Program
{
static void Main(string[] args)
{
var server = new BackgroundWorker();
server.DoWork += new DoWorkEventHandler(server_DoWork);
server.RunWorkerAsync();
var port = new SerialPort();
port.PortName = "COM2";
port.Open();
string input = "";
Console.WriteLine("Client on COM2: {0}", Thread.CurrentThread.ManagedThreadId);
while (input != "/quit")
{
input = Console.ReadLine();
if (input != "/quit")
{
var data = ASCIIEncoding.ASCII.GetBytes(input);
port.Write(data, 0, data.Length);
}
}
port.Close();
port.Dispose();
}
static void server_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine("Listening on COM1: {0}", Thread.CurrentThread.ManagedThreadId);
var port = new SerialPort();
port.PortName = "COM1";
port.Open();
port.ReceivedBytesThreshold = 15;
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
}
static void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var port = (SerialPort)sender;
int count = 0;
byte[] buffer = new byte[port.ReadBufferSize];
count = ((SerialPort)sender).Read(buffer, 0, buffer.Length);
string echo = ASCIIEncoding.ASCII.GetString(buffer,0,count);
Console.WriteLine("-->{1} {0}", echo, Thread.CurrentThread.ManagedThreadId);
}
}
결과는 다음과 같을 수 :
이 COM1에 듣기 : 6 클라이언트를 COM2에 10 이 내가 보내는 일부 샘플 데이터가 난 아주 간단한 (바보) 작은 예를했다 ---> 6 이것은 내가 주 스레드에서 발생그래서 포트에서 데이터를 읽는 보내 일부 샘플 데이터 ....
이 내 문제를 일으키는 무엇의 일부가 될 수 있음은? 또한private void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
var port = (SerialPort)sender;
while (port.BytesToRead > 0)
{
int byte_count = port.BytesToRead;
byte[] buffer = new byte[byte_count];
int read_count = port.Read(buffer, 0, byte_count);
// PROCESS DATA HERE
}
}
난 그냥 절차 port_DataReceived의 큐 목록에서 데이터를 삽입하도록 권장하고, 데이터를 수행 할 것입니다 :
코드의 마지막 섹션은 어디에 있습니까? '데이터'변수의 출처는 어디입니까? –
위 코드는 IDataCollector가 이벤트를 발생시켜 전체 데이터 프레임을 수집했음을 나타낼 때 호출됩니다. WPF Windows에 있습니다. 그러나 IDataTransportServer 또는 IDataCollector 구현 코드에서 log.Warn (".....") 문을 추가하더라도 SerialCommunication은 엉망이됩니다. '데이터'는 단순히 직렬 줄 번호 : buffer.GetSubByteArray (0, count) – TimothyP
그냥 어떤 코드라도 직렬 통신이 잘못 될 수 있습니다 ... – TimothyP