我正在尝试通过串行端口通信进行聊天。这个聊天必须在 WPF 项目中有一个界面,我已经制作了界面和所有内容。我陷入了通过串口接收响应的困境。我已经尝试从串行端口添加 DataReceived 事件,但我担心我使用错误,因为我以前从未用 C# 编程过。这是一个非常简单的代码。
我需要做的是从串行端口接收信息并将其显示在文本块中,就像在简单的聊天窗口中一样。
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();
}
当我在 .exe 文件中运行它时,它崩溃并显示InvalidOperationException
有内部异常(翻译):
“实现该调用的子进程无法获得对此的访问权限
对象,因为专有是另一个子流程。”
事件是从调用它们的线程中触发的,在串行端口(或任何通信层)的情况下,这将确实不在 UI 线程上。
但是,UI 操作must在 UI 线程上完成。所以下面的代码将会失败:
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
visor.Inlines.Add("Data Received:");
visor.Inlines.Add(indata);
因为您正在从错误的线程修改 UI 元素。解决方案是使用BeginInvoke
(MSDN http://msdn.microsoft.com/en-us/library/cc190824(v=vs.110).aspx) 将操作编组到 UI 线程上:
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Dispatcher.BeginInvoke(() =>
{
visor.Inlines.Add("Data Received:");
visor.Inlines.Add(indata);
}, null);
附言。你的例外的翻译似乎不正确;如果这是问题所在,您将看到的例外是(英文):
跨线程操作无效:从其他线程访问控制
比创建它的线程更重要。
(或者非常相似的东西)。我无法识别提供的文本,并且鉴于您的代码,看起来这就是您遇到的情况。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)