简体   繁体   English

使用c#进行串行数据接收和处理的最佳方法是什么?

[英]What is the best approach for serial data reception and processing using c#?

I am pretty new to coding with some experience in ASM and C for PIC. 我对使用PIC的ASM和C有一些经验的编码非常陌生。 I am still learning high level programming with C#. 我仍在学习使用C#进行高级编程。

Question

I have a Serial port data reception and processing program in C#. 我在C#中有一个串行端口数据接收和处理程序。 To avoid losing data and knowing when it was coming, I set a DataReceived event and loop into the handling method until there were no more bytes to read. 为了避免丢失数据并知道何时到达,我设置了一个DataReceived事件并循环进入处理方法,直到没有更多的字节可读取为止。

When I attempted this, the loop continued endlessly and blocked my program from other tasks (such as processing the retrieved data) when I continuously received data. 当我尝试这样做时,循环不断地继续,并在我连续接收数据时使我的程序无法执行其他任务(例如处理检索到的数据)。

I read about threading in C#, I created a thread that constantly checks for SerialPort.Bytes2Read property so it will know when to retrieve available data. 我读到有关C#中的线程的信息,我创建了一个线程,该线程不断检查SerialPort.Bytes2Read属性,以便它知道何时检索可用数据。

I created a second thread that can process data while new data is still being read. 我创建了第二个线程,可以在仍在读取新数据的同时处理数据。 If bytes have been read and ReadSerial() has more bytes to read and the timeout (restarted every time a new byte is read from the serial) they can still be processed and the frames assembled via a method named DataProcessing() which reads from the same variable being filled by ReadSerial(). 如果已经读取了字节并且ReadSerial()有更多的字节要读取并且超时(每次从串行读取一个新字节时都会重新启动),则仍然可以处理它们,并通过一个名为DataProcessing()的方法组装帧,该方法从由ReadSerial()填充相同的变量。

This gave me the desired results, but I noticed that with my solution (both ReadSerial() and DataProcessing() threads alive), CPU Usage was skyrocketed all the way to 100%! 这给了我理想的结果,但是我注意到在我的解决方案( ReadSerial()DataProcessing()线程都处于活动状态)下,CPU使用率一路飙升至100%!

How do you approach this problem without causing such high CPU usage? 在不引起如此高的CPU使用率的情况下,如何解决此问题?

public static void ReadSerial() //Method that handles Serial Reception
{
    while (KeepAlive) // Bool variable used to keep alive the thread. Turned to false
    {                 // when the program ends.
        if (Port.BytesToRead != 0)
        {
            for (int i = 0; i < 5000; i++) 
            {

             /* I Don't know any other way to 
                implement a timeout to wait for 
                additional characters so i took what 
                i knew from PIC Serial Data Handling. */

                if (Port.BytesToRead != 0)
                {
                    RxList.Add(Convert.ToByte(Port.ReadByte()));
                    i = 0;

                    if (RxList.Count > 20) // In case the method is stuck still reading
                        BufferReady = true; // signal the Data Processing thread to 
                 }                          // work with that chunk of data.

                 BufferReady = true; // signals the DataProcessing Method to work      
            }                        // with the current data in RxList.
        }         
    }    
}

I can not understand completely what you are meaning with the "DataReceived" and the "loop". 我无法完全理解“ DataReceived”和“ loop”的含义。 I am also working a lot with Serial Ports as well as other interfaces. 我还在串口和其他接口上进行了大量工作。 In my application I am attaching to the DataReceived Event and also reading based on the Bytes to read, but I dont use a loop there: 在我的应用程序中,我将附加到DataReceived事件,并且还将基于要读取的字节进行读取,但是在此我不使用循环:

int bytesToRead = this._port.BytesToRead;
var data = new byte[bytesToRead];
this._port.BaseStream.Read(data , 0, bytesToRead);

If you are using a loop to read the bytes I recommend something like: 如果您正在使用循环读取字节,则建议使用以下内容:

  System.Threading.Thread.Sleep(...);

Otherwise the Thread you are using to read the bytes is busy all the time. 否则,您用来读取字节的线程一直很忙。 And this will lead to the fact that other threads cannot be processed or your CPU is at 100%. 这将导致无法处理其他线程或您的CPU处于100%状态的事实。

But I think you don't have to use a loop for polling for the data if you are using the DataReceived event. 但我认为,如果使用DataReceived事件,则不必使用循环来轮询数据。 If my undertanding is not correct or you need further information please ask. 如果我的理解不正确或您需要更多信息,请询问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM