2

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."

dsolimano
  • 8,870
  • 3
  • 48
  • 63
  • 2
    Can you post the text of the error or does it crash without giving an error? – orgtigger Oct 08 '14 at 23:07
  • If it is "without error" make sure your debugger is attached so you can see the actual exception. – BradleyDotNET Oct 08 '14 at 23:13
  • It crashes without giving an error but a debug option. When I hit debug it says an InvalidOperationException wasn't controlled. As additional information it says: "The subprocess that realized the call cannot gain Access to this object because the propietary is another subprocess." That happens when the serial port is supposed to recieve information. – Kassandra Hinojosa Rodriguez Oct 08 '14 at 23:13
  • Where can I find the InnerException? When I click debug it opens Visual Studio but I don't know about the InnerException. – Kassandra Hinojosa Rodriguez Oct 08 '14 at 23:17
  • I think something was lost in translation there. Is this a cross-thread invocation issue? If you click "View more" (or something like that) in the exception dialog, you can see the inner exception. Looking at your code, I'm pretty sure this is a cross-thread issue. – BradleyDotNET Oct 08 '14 at 23:18
  • System.InvalidOperationException not controlled _HResult=-2146233079 _message=The subprocess that realized the call cannot gain Access to this object because the propietary is another subprocess. – Kassandra Hinojosa Rodriguez Oct 08 '14 at 23:30
  • When it enters the code, the debugger selects the line 'visor.Inlines.Add(indata);' as the one with the problema, and in variables it gives me the variable sender, e and sp with a big red x by their sides. – Kassandra Hinojosa Rodriguez Oct 08 '14 at 23:32

1 Answers1

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.

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
  • Thank you very much!! Now I understand the use of this, and definitely understood why the BeginInvoke method was needed, now it is working, and yeah I think my translation was wrong and tried to switch Visual Studio to english but didn't find the option. Thank you very much. – Kassandra Hinojosa Rodriguez Oct 08 '14 at 23:52
  • @KassandraHinojosaRodriguez No problem. Especially with exceptions, getting it in original english form will help when posting to places like this, as experienced programmers will recognize it in a *heartbeat*. Remember to include such details in your questions in the future as well. Glad I was able to help! – BradleyDotNET Oct 08 '14 at 23:55
  • I'll try and do that so that the next time I can post it in english. Thank you. – Kassandra Hinojosa Rodriguez Oct 08 '14 at 23:59