我正在编写一个应用程序,它涉及与设备的串行通信等。 (在C#中)。我在一些具体的例子中看到了一些示例代码。
在第一个例子中,代码基于一个Background控件,它有一个while循环,用于检查是否有从串口读取的数据(另一个控件)以及何时进行某些处理
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{ serialPort1.Open();
while (backgroundWorker1.CancellationPending == false)
{
if (serialPort1.BytesToRead >= 240)
{
serialPort1.Read(RDATA, 0, 240);
//Some other process
}
}
serialPort1.Close();
}
第二个例子是完全不同的。这涉及代表和活动。在这种情况下,串行端口(在代码中创建)具有事件" DataReceived"。为此,我们添加了一个事件处理程序
ComPort.DataReceived +=
new System.IO.Ports.SerialDataReceivedEventHandler(port_DataReceived_1);
然后定义port_DataReceived_1函数,其中读取输入数据
private void port_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
{
InputData = ComPort.ReadExisting();
if (InputData != String.Empty)
{
this.BeginInvoke(new SetTextCallback(SetText), new object[] { InputData });
}
}
private void SetText(string text)
{
this.rtbIncoming.Text += text;
}
无论如何,我可以在这里看到两种不同风格的编码串行通信。一方面,我们有一个常量轮询(通过while),如果它不在另一个线程上,它将阻止程序的其余部分。虽然它是在不同的线程中完成的。 另一方面,我们有中断,其中处理仅在事件发生时完成而不是在其余时间完成。这一切都是在主线上完成的。
我的问题是哪种方式更可取。我正在成像第一种方法,即使它在不同的线程上占用了大量的计算机资源,甚至可能将CPU的负载提高到100%或者其他什么。 我更倾向于做第二个但是又一次在一个线程中。 有什么建议,对此提出建议吗?
(我的应用程序不仅涉及串行通信,还涉及处理收到的数据,甚至可能涉及机器学习)
答案 0 :(得分:2)
你绝对应该使用第二个选项,这可能由I/O Completion Port线程处理。如果您正在编写WinForms应用程序,那么您需要确保检查InvokeRequired标志并通过将委托传递给Invoke方法对主线程执行任何UI操作