C#中串行端口上的多端口异步I / O

时间:2009-03-23 20:39:00

标签: c# .net serial-port

我正在尝试为C#中的多个单元编写一个串行I/ORS-232)的测试应用程序,但由于缺乏线程经验,我遇到了一个问题所以我正在招揽对最有名的方法的反馈。

我有一个COM端口COM1-16池,每个端口都可以随时读/写,我需要能够同时管理它们。这是线程池的情况吗?有关构建此applet的一些指导意见吗?

编辑: 经过审查,我想知道我真的需要在这里做异步线程,我可以只为每个COM端口维护状态,并为每个COM端口单独进行流逻辑(即状态机)。

4 个答案:

答案 0 :(得分:2)

围绕串口的许多困难都围绕着一个假设。假设串行端口以方便的方式和预期的方式接收数据。

这是一个例子。我知道我的GPS接收器发送线路(以CRLF结束)。这是NMEA句子之一的一个例子:

$ GPGSV,3,1,11,10,75,053,29,29,52,311,32,24,50,298,30,02,39,073,30 * 77

但是,串行端口DataReceived事件处理程序可能(通常在我的PC上)使用该数据块进行多次激活。

事件火灾 - 数据

1 $
2 GPGSV,3,1,11,10
3 ,75,053,29,29,52,311,32,24,50,298,30,02,39,073,30*77

我没有与此作斗争,而是创建了一些在事件触发时接收数据的例程,并将其排队。当我需要数据时,我会调用一些其他例程,将数据重新组合在块大小我想要中。因此,使用我的示例第一次和第二次调用read line(我的readline)时,我得到一个空答案。 我第三次收到整个NMEA的判决。

坏消息是我没有C#。代码在这里SerialPort

根据端口的速度,代表可能不是一个好的选择。我使用委托以接近1Mbps的速度测试我的例程,而不是使用委托。在不使用代表的情况下,这是一个更好的选择。

以下是知情人士的一些提示

Kim Hamilton

答案 1 :(得分:1)

如果你使用背景工作者,你将不会抓小 数据片段,你将获得整个字符串。你需要 类似的东西:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    try
    {
        serialPort1.Open();
        if (serialPort1.IsOpen)
        {
            while (keepReading)
            {
                backgroundWorker1.ReportProgress(0, serialPort1.ReadLine());
                //backgroundWorker1.ReportProgress(0, sentence.Split(','));
                // split_gps_data();
            }
        }
    }
}

答案 2 :(得分:0)

处理此问题的.NET方法是使用事件和委托。这将最终创建多个线程,但它将以一种意味着您不显式创建它们的方式这样做。如果您创建一个事件处理程序并将其添加到每个端口的DataReceived事件,那么当任何端口接收数据时,将在单独的线程上调用事件处理程序。当然,这意味着该方法必须是可重入的,并且必须保护对任何共享数据结构的访问以防止并发访问。

您的处理程序例程将执行以下操作:

  1. 调用ReadExisting以获取可用数据。
  2. 处理数据。
  3. 完成。

答案 3 :(得分:-1)

您需要知道接收器以何种速度吐出数据。它是一秒钟,每秒两次,5次......

我有同样的问题阅读GPS数据。您需要在C#中使用backgroundworker来更新变量,屏幕。