![](/img/trans.png)
[英]How do I troubleshoot SerialPort.Read() always return 0 in C#?
[英]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.