C# “C”;使用;串行端口传输,数据丢失

C# “C”;使用;串行端口传输,数据丢失,c#,serial-port,using,data-loss,C#,Serial Port,Using,Data Loss,我是这个论坛的新手,我有一个问题困扰了我一段时间。 我的设置是通过usb/uart转换器连接到我的电脑的串行字符显示器。在C++风格的独立写缓冲线程中,我通过SerialPoT类向显示器发送字节: private void transmitThread(){ while(threadAlive){ if(q.Count > 0){ // Queue not empty byte[] b = q.Dequeue(); s

我是这个论坛的新手,我有一个问题困扰了我一段时间。 我的设置是通过usb/uart转换器连接到我的电脑的串行字符显示器。在C++风格的独立写缓冲线程中,我通过SerialPoT类向显示器发送字节:

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#特性,即“using”语句,并且只在需要时打开端口,如下所示:

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字节字节字节数组的三分之一。我尝试了线程的不同优先级设置,但没有任何变化

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


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

我认为您没有抓住使用块的要点。典型的using块如下所示:

using (var resource = new SomeResource())
{
    resource.DoSomething();
}
开口发生在一开始。通常作为构造函数的一部分。但有时在使用块的第一行


但我看到的一个重大危险信号是,交割是自动进行的。您不需要调用
.Close()

我认为您没有抓住使用块的要点。典型的using块如下所示:

using (var resource = new SomeResource())
{
    resource.DoSomething();
}
开口发生在一开始。通常作为构造函数的一部分。但有时在使用块的第一行


但我看到的一个重大危险信号是,交割是自动进行的。您不需要调用
.Close()

如果串行设备的成功运行取决于对
线程的调用。Sleep
则线程可能在某个点被中断,足以使数据传输与设备不同步。很可能有办法解决这个问题,但我要做的第一件事是尝试使用.NET类。该方法与你想做的非常类似,在这些文章中有C++代码示例。

< P>如果你的串行设备的成功操作依赖于对代码>线程的调用。睡眠< /代码>,那么线程可能在某个点被中断,足以使数据传输与设备同步。很可能有办法解决这个问题,但我要做的第一件事是尝试使用.NET类。这个方法和你想做的非常类似,在这些文章中有C++代码例子。出错的事情,大致按您遇到的顺序排列:

  • 串行端口驱动程序会丢弃传输缓冲区中剩余的、在关闭端口时尚未传输的所有字节。这就是你现在看到的

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

  • 关闭端口允许另一个程序获取端口并打开它。无法共享串行端口,当您再次尝试打开时,程序将失败


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

不,这是一个非常糟糕的主意。出错的事情,大致按您遇到的顺序排列:

  • 串行端口驱动程序会丢弃传输缓冲区中剩余的、在关闭端口时尚未传输的所有字节。这就是你现在看到的

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

  • 关闭端口允许另一个程序获取端口并打开它。无法共享串行端口,当您再次尝试打开时,程序将失败


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

那些
Sleep()
调用会降低吞吐量。是否有一个
Flush()
方法可以调用串行端口对象?如果使用using块,则不需要关闭…@RobertHarvey Dispose或Close将刷新流。是的,我知道睡眠(100)时间很长,但似乎在接收到SpecialFunctionCommandBytes后显示需要一些时间。对于字符串输入,它不在乎,但现在我让它不管怎样都休眠。那些
sleep()
调用会降低吞吐量。是否有一个
Flush()
方法可以调用串行端口对象?如果使用using块,则不需要关闭…@RobertHarvey Dispose或Close将刷新流。是的,我知道睡眠(100)时间很长,但似乎在接收到SpecialFunctionCommandBytes后显示需要一些时间。对于字符串输入它不在乎,但是现在我让它不管。所以基本上你建议我不要使用'using'语句,而保留我的原始设计?那么我需要添加一个try-catch。所以基本上你建议我不要使用“using”语句,而是保留我的原始设计?我需要添加一个尝试捕捉然后。