Получение данных от последовательного порта в C# при обновлении интерфейса - PullRequest
0 голосов
/ 27 марта 2020

Мой вопрос: как вы обновляете свой пользовательский интерфейс данными из serialport, в то же время обновляя другие компоненты пользовательского интерфейса? Я пытался использовать фоновый рабочий, но он, кажется, блокирует интерфейс во время потоковой передачи данных.

Изображение формы:

Main UI form

Мой код:

public partial class Form1 : Form
{

    static bool _continue;
    static SerialPort _serialPort;

    BackgroundWorker dataWorker;

    string message;

    public delegate void UpdateListboxData();





    private void buttonPortConnect_Click(object sender, EventArgs e)
    {




        // Set the read/write timeouts
        _serialPort.ReadTimeout = 500;
        _serialPort.WriteTimeout = 500;

        _serialPort.Open();
        _continue = true;

        dataWorker = new BackgroundWorker();
        dataWorker.RunWorkerAsync();
        dataWorker.DoWork += StartDataWork;



    }


    private void StartDataWork(object sender, DoWorkEventArgs e)
    {
        Delegate del = new UpdateListboxData(DataRead);
        this.Invoke(del);
    }


    private void DataRead()
    {
        while (_continue)
        {
            try
            {
                message = _serialPort.ReadLine();

            }
            catch (TimeoutException) { }
        }
    }
}

Ответы [ 3 ]

0 голосов
/ 27 марта 2020

Вы не должны читать данные внутри функции invoke'd. Это блокирует ваш пользовательский интерфейс.

Либо считывайте данные непосредственно в «DoWork» и вызывайте делегата только с данными.

Или вы можете использовать событие DataReceived SerialPort.

0 голосов
/ 27 марта 2020

Вы должны использовать событие последовательного порта DataReceived и делегат

    private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {

                if (TextBox.InvokeRequired)
                    TextBox.Invoke(new myDelegate(updateTextBox));

        }
        public delegate void myDelegate();

        public void updateTextBox()
        {
            int iBytesToRead = serialPort1.BytesToRead;
            //Your Codes For reding From Serial Port Such as this:
            char[] ch = new char[?];
            serialPort1.Read(ch, 0, ?? ).ToString();
            //........

        }
0 голосов
/ 27 марта 2020

Способ обновления пользовательского интерфейса winforms заключается в использовании if (control.InvokeRequired) {...} и Invoke, как показано в примере здесь Как обновить GUI из другого потока?

...