问题
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