Serial port communication display

我怕爱的太早我们不能终老 提交于 2020-01-04 09:08:05

问题


I'm trying to make a chat with serial port communication. This chat has to have an interface in a WPF Project, I already made my interface and everything. I'm stuck in receiving the response through the serial port. I already tried adding a DataReceived event from the serial port but I'm afraid I'm using it wrong since I have never programmed in C# before. It is a really simple code. What I need to do is receive the information from the serial port and display it in a text block as it would look in a simple chat window.

        InitializeComponent();
        _serialPort = new SerialPort();

        foreach (string s in SerialPort.GetPortNames())
        {
            listaComs.Items.Add(s);
        }


    }

    private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;
        string indata = sp.ReadExisting();
        visor.Inlines.Add("Data Received:");
        visor.Inlines.Add(indata);
    }
    private void enviarClick(object sender, RoutedEventArgs e)
    {
        _serialPort.WriteLine(escribir.Text);
        visor.Inlines.Add("Yo: " + escribir.Text + Environment.NewLine);
    }

    private void cambiarTexto(object sender, MouseButtonEventArgs e)
    {
        if (escribir.Text == "Escriba su texto")
        {
            escribir.Text = "";
        }
    }

    private void inicializarSerial()
    {
        // Poner las propiedades correctas.
        _serialPort.BaudRate = 9600;
        _serialPort.Parity = Parity.None;
        _serialPort.StopBits = StopBits.One;
        _serialPort.DataBits = 8;
        _serialPort.Handshake = Handshake.None;
        _serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

        // Poner los timeouts de escritura y lectura
        _serialPort.ReadTimeout = 500;
        _serialPort.WriteTimeout = 500;
    }

    private void conectarCom(object sender, RoutedEventArgs e)
    {
        string seleccion = listaComs.SelectedItem.ToString();
        _serialPort.PortName = seleccion;
        inicializarSerial();
        _serialPort.Open();
        _continue = true;
        visor.Text = "";
    }

    private void desconectarCom(object sender, RoutedEventArgs e)
    {
        _serialPort.Close();
    }

When I run this in the .exe file it crashes down with an InvalidOperationException with inner exception (translated):

"The subprocess that realized the call cannot gain Access to this object because the propietary is another subprocess."


回答1:


Events are fired from the thread that invoked them, and in the case of a serial port (or any comms layer), this is going to definitely not be on the UI thread.

However, UI operations must be done on the UI thread. So the code below will fail:

    SerialPort sp = (SerialPort)sender;
    string indata = sp.ReadExisting();
    visor.Inlines.Add("Data Received:");
    visor.Inlines.Add(indata);

Because you are modifying a UI element from the wrong thread. The solution is to use BeginInvoke (MSDN) to marshal the operation onto the UI thread:

    SerialPort sp = (SerialPort)sender;
    string indata = sp.ReadExisting();

    Dispatcher.BeginInvoke(() =>
    {
       visor.Inlines.Add("Data Received:");
       visor.Inlines.Add(indata);
    }, null);

PS. The translation of your exception didn't seem right; if this was the issue, the exception you will see is (in English):

Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on.

(Or something very similar). I didn't recognize the provided text, and given your code, it looks like this is what you encountered.



来源:https://stackoverflow.com/questions/26267816/serial-port-communication-display

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!