Continuous read from serial port asynchronously

I will just talk about it, saying that I started using Async today, so I have a very limited understanding of what I am doing.

Earlier, I used streams to read data from the serial port, processed this data to write data, and then wrote them. I had 1 read data stream and placing it in the buffer, another data processing stream from the buffer and the final stream writing it. That way, if I clicked the button, I could send additional data.

Now I'm just trying to learn and I'm sure I'm doing everything right, so I'm trying to read data from the serial port and add this data to the multi-line text box. Here is the code:

Connect to the serial port, if successful, call UpdateMessageBoxwhich is asynchronous:

private void serialConnectClick(object sender, EventArgs e)
{
    if (!_serialConnected)
    {
        _serialConnected = SerialConnect(portCombo.Text, int.Parse(baudCombo.Text));
        if (!_serialConnected)
        {
            portCombo.SelectedIndex = 0;
            messageTextBox.Text += "Failed to connect.\r\n";
            return;
        }

        serialConnectBtn.Text = "Disconnect";
        serialStatusLabel.Text = "Serial: Connected";
        serialStatusLabel.ForeColor = Color.Blue;
        messageTextBox.Text += "Connected\r\n";
        VDIportCombo.Enabled = false;
        soundSuccess.Play();
        UpdateMessageBox(); // this is an async function
    }
}

This continuously calls ReadLineAsyncand adds the result to the text box:

public async Task UpdateMessageBox()
{
    messageTextBox.Text += "Reading data from serial.";
    while (_serialConnected)
    {
        string message = await SerialReadLineAsync(serial);
        messageTextBox.Text += message;
    }
}

And this does ReadAsyncon SerialPort.BaseStreamand returns only data when we get the full line (indicated by a newline):

async Task<string> SerialReadLineAsync(SerialPort serialPort)
{
    byte[] buffer = new byte[1];
    string result = string.Empty;
    Debug.WriteLine("Let start reading.");

    while (true)
    {
        await serialPort.BaseStream.ReadAsync(buffer, 0, 1);
        result += serialPort.Encoding.GetString(buffer);

        if (result.EndsWith(serialPort.NewLine))
        {
            result = result.Substring(0, result.Length - serialPort.NewLine.Length);
            result.TrimEnd('\r','\n');
            Debug.Write(string.Format("Data: {0}", result));
            result += "\r\n";
            return result;
        }
    }
}

Am I doing everything right? Can I call the async method from the user interface thread? Visual studios tell me that I will have to wait, but that just assumes that.

, , await UpdateMessageBox. , , , myReadThread.Start(), - async?

: , , , "" , .

+4
1

:

private void serialConnectClick(object sender, EventArgs e)

to

private async void serialConnectClick(object sender, EventArgs e)

... UpdateMessageBox(); :

await UpdateMessageBox().ConfigureAwait(true);

UpdateMessageBox ConfigureAwait(true), (UI), messageTextBox.Text += message; :

public async Task UpdateMessageBox()
{
    messageTextBox.Text += "Reading data from serial.";
    while (_serialConnected)
    {
        string message = await SerialReadLineAsync(serial).ConfigureAwait(true);
        messageTextBox.Text += message;
    }
}

SerialReadLineAsync :

await serialPort.BaseStream.ReadAsync(buffer, 0, 1);

... :

await serialPort.BaseStream.ReadAsync(buffer, 0, 1).ConfigureAwait(false);

... SerialReadLineAsync .

- " ", , await a async async , , await ed. .

+6

Source: https://habr.com/ru/post/1649973/


All Articles