последовательный порт, читающий несколько строк - PullRequest
0 голосов
/ 04 февраля 2019

У меня есть доска, с которой я пытаюсь общаться.Когда я даю ему несколько команд, он должен возвращать строковые сообщения обратно и должен публиковаться в текстовом поле.Моя проблема в том, что когда устройство должно возвращать несколько строк текста, публикуется только одна из строк.Я пробовал также с ReadExisting вместо ReadLine, но после одной команды я получаю только пустые строки.

public partial class Form1 : Form        
{
    private string x;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        serialPort1.Open();
        timer1.Start();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        serialPort1.WriteLine(textBox1.Text);
        textBox1.Clear();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {

        if (String.IsNullOrEmpty(x))
        {

        }
        else
        {
            textBox2.AppendText(x + "\n\r");
            x = "";
        }

    }

    private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        x = serialPort1.ReadLine();
        //x = serialPort1.ReadExisting();
    }

    private void Form1_Closing(object sender, EventArgs e)
    {
        serialPort1.Close();
        timer1.Stop();
    }

    private void textBox2_TextChanged(object sender, EventArgs e)
    {

    }
}

1 Ответ

0 голосов
/ 04 февраля 2019

Вам всегда лучше избегать DataReceived и просто использовать BaseStream.Например:

private async void Form1_Load(object sender, EventArgs e)
{
    serialPort1.Open();
    using (var reader = new StreamReader(serialPort1.BaseStream)) {
         while (serialPort1.IsOpen) {
             string x = await reader.ReadLineAsync();
             textBox2.AppendText(x + "\r\n");
         }
    }
}

Ключевое слово await автоматически управляет синхронизацией обратно в поток пользовательского интерфейса - вам не нужно Invoke, вы не получаете межпоточные сбои, вы не делаетеполучить второй вызов вашего обработчика событий, запущенного, пока первый еще работает, вы не получите условия гонки от нескольких потоков, обращающихся к одной и той же переменной.Гораздо проще разобраться.

В качестве проблемы стиля я бы не поместил этот код непосредственно в ваш обработчик событий Form Load, я бы поместил его в вспомогательную функцию с соответствующим названием (возможно, OpenAndReadSerial())и назовите это переопределенным OnLoad().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...