簡體   English   中英

C# - SerialPort.read() 速度問題

[英]C# - SerialPort.read() speed issue

我的代碼旨在從串行設備獲取數據並將其內容打印到 MS Forms 應用程序。 我使用的 IDE 是 Visual Studio 2019 - Community。

該設備確實發送了一個可變大小的數據包。 首先,我必須解碼數據包“標頭”以獲得進一步處理的關鍵信息,即第一個數據包通道以及數據包長度。

由於數據包既不包含行結尾,也不包含末尾的固定字符,因此SerialPort.ReadTo()SerialPort.ReadLine()函數沒有用處。 因此只能使用SerialPort.Read(buf,offset,count)

由於發送相當大的數據包(512 字節)確實需要時間,我實現了一個 function 來計算所需的等待時間,定義為(1000ms/baud-rate*(8*byte-count))+100ms

在測試時,我遇到了延遲,遠遠超過了所需的等待時間,因此對 function 的不同部分實施了測量 function。

在常規情況下(具有所需的等待時間)我除了這樣的控制台日志: Load Header(+122ms) Load Data (+326ms) Transform (+3ms)

但它只是對於一些可變數量的記錄,通常是 10,之后執行時間要差得多:

Load Header(+972ms) Load Data (+990ms) Transform (+2ms)

在這里你可以看到完整的 function:

private void decodeWriteResponse(int identifier, object sender, SerialDataReceivedEventArgs e)
    {
        /* MEASURE TIME NOW */
        long start = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();

        var serialPort = (SerialPort)sender;                    //new serial port object
        int delay = ComPort.getWaitTime(7);                     //Returns the wait time (1s/baudrate * bytecount *8) +100ms Additional
        Task.Delay(delay).Wait();                               //wait until the device has send all its data!
        byte[] databytes = new byte[6];                          //new buffer
        try
        {
            serialPort.Read(databytes, 0, 6);                    //read the data
        }
        catch (Exception) { };

        /* MEASURE TIME NOW */
        long between_header = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();

        /* Read the Data from Port */
        int rec_len = databytes[1] | databytes[2] << 8;         //Extract number of channels
        int start_chnl = databytes[3] | databytes[4] << 8;      //Extract the first channel

        delay = ComPort.getWaitTime(rec_len+7);                 //get wait time
        Task.Delay(delay).Wait();                               //wait until the device has send all its data!
        byte[] buf = new byte[rec_len-3];                       //new buffer

        try
        {
            serialPort.Read(buf, 0, rec_len-3);                  //read the data
        }
        catch (Exception) {}


        /* MEASURE TIME NOW */
        long after_load = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();

        /* Now perform spectrum analysis */
        decodeSpectrumData(buf, start_chnl, rec_len-4);

       /*MEASURE TIME NOW */
       long end = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
       Form.rtxtDataArea.AppendText("Load Header(+" + (between_header - start).ToString() + "ms) Load Data (+" + (after_load - between_header).ToString() + "ms) Transform (+" + (end - after_load) + "ms)\n");



        /*Update the Write handler */
        loadSpectrumHandler(1);

    }

什么可能導致這個問題? 我已經在 Visual Studio 中使用“debug”進行了測試,並且作為“Release”獨立進行了測試,但沒有區別。

與其試圖弄清楚一條消息到達端口需要多長時間,為什么不直接在循環中讀取數據,直到獲得所有數據? 例如,讀取 header 並計算 msg 大小。 然后讀取該字節數。 前任:

// See if there are at least enough bytes for a header
if (serialPort.BytesToRead >= 6) {
    byte[] databytes = new byte[6];
    serialPort.Read(databytes, 0, 6);
    // Parse the header - you have to create this function
    int calculatedMsgSize = ValidateHeader(databytes);
    byte [] msg = new byte[calculatedMsgSize];
    int bytesRead = 0;
    while (bytesRead < calculatedMsgSize) {
        if (serialPort.BytesToRead) {
            bytesRead += serialPort.Read(msg, bytesRead,
                Math.min(calculatedMsgSize - bytesRead, serialPort.BytesToRead));
        }
    }
    // You should now have a complete message
    HandleMsg(msg);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM