0

我是这个论坛的新手,有一个问题困扰了我一段时间。我的设置是使用 USB/uart 转换器连接到我的电脑的串行字符显示器。我正在以 C++ 样式在单独的写入缓冲区线程中通过 serialPort 类将字节传输到显示器:

private void transmitThread(){
    while(threadAlive){
        if(q.Count > 0){ // Queue not empty
            byte[] b = q.Dequeue();
            s.Write(b,0,b.Length);
            System.Threading.Thread.Sleep(100);
        }
        else{ // Queue empty
            System.Threading.Thread.Sleep(10);
        }
    }
}

假设串行端口已经打开,这可以完美运行并将所有数据传输到显示器。尽管此代码段中根本没有异常处理。因此,我正在研究实现一个典型的 C# 功能,即“使用”语句,并且只在需要时打开端口,如下所示:

private void transmitThread(){
    while(threadAlive){
        if(q.Count > 0){ // Queue not empty
            byte[] b = q.Dequeue();
            using(s){ //using the serialPort
                s.Open();
                s.Write(b,0,b.Length);
                s.Close();
            }
            System.Threading.Thread.Sleep(100);
        }
        else{ // Queue empty
            System.Threading.Thread.Sleep(10);
        }
    }
}

这个函数的问题是,它只传输随机数量的数据,通常约为 80 字节字节数组的三分之一。我尝试了线程的不同优先级设置,但没有任何变化。

我是否遗漏了一些重要的东西,或者我只是在发送请求后关闭端口太快?

我希望你能帮助我。谢谢 :)

4

3 回答 3

4

不,那是一个非常糟糕的主意。出错的地方,大致按照您遇到的顺序:

  • 当您关闭端口时,串行端口驱动程序会丢弃发送缓冲区中尚未发送的任何字节。这就是你现在看到的。

  • SerialPort.Close() 的 MSDN 文章警告您必须“等待一段时间”才能再次打开端口。有一个内部工作线程需要关闭。您必须等待的时间量未指定,并且是可变的,具体取决于机器负载。

  • 关闭一个端口允许另一个程序获取该端口并打开它。串口不能共享,再次打开程序会失败。

串行端口根本不是为了即时打开和关闭而设计的。只在程序开始时打开它,结束时关闭它。完全不调用 Close() 是完全可以接受的,并且可以避免死锁情况。

于 2012-07-17T20:33:01.577 回答
0

我认为您错过了 using 块的要点。典型的 using 块如下所示:

using (var resource = new SomeResource())
{
    resource.DoSomething();
}

开场发生在最开始。通常作为构造函数的一部分。但有时在 using 块的第一行。

但我看到的大红旗是关闭自动发生。你不需要.Close()来电。

于 2012-07-17T20:26:17.177 回答
0

如果串行设备的成功操作依赖于对的调用,Thread.Sleep那么线程可能在某个时候被中断,足以使数据传输与设备不同步。很可能有办法解决这个问题,但我要做的第一件事是尝试改用 .NET SerialPort类。Write方法与您要执行的操作非常相似,并且那些文章中有 C++ 代码示例。

于 2012-07-17T20:31:47.780 回答