我有一个可以在串行,GPIB,USB和以太网上读写的程序。它有一个选项卡,用于与内部显示端口通信的文本框进行通信。其中一个选项卡列为All Comms,该文本框包含来自所有通信方法的数据。我目前正在处理代码的串口部分,我的程序一直在冻结。有一半的时间我运行我的代码它没有问题写入两个选项卡。另一半当它试图写入未选中的选项卡内的文本框时会冻结(通过一次一行代码找到)。
我拉出了标签控件之外的文本框,这解决了冻结问题。当程序冻结时,它不显示错误消息并且不会崩溃,因此没有崩溃报告(让它在周末运行并且它从未完成崩溃)。
我认为我需要选择其他选项卡然后写入它,但为什么代码在我运行它的一半时间内正常工作?
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
rxString = rxString + serialPort1.ReadExisting();
if (rxString == "\b")
{
//Removes 1 character when backspace is the key pressed
rxSerialTextBox.ReadOnly = false;
rxSerialTextBox.Select(rxSerialTextBox.TextLength - 1, rxSerialTextBox.TextLength);
rxSerialTextBox.SelectedText = String.Empty;
rxSerialTextBox.ReadOnly = true;
rxString = "";
}
while (rxString.Length != 0)
{
try
{
while (rxString.Length != 0)
{
if (rxString.IndexOf("\r\n") == 0)
{
//Adds a newline when newline is the next characters in the string
rxString = rxString.Substring(rxString.IndexOf("\r\n") + 2);
rxAllCommsTextBox.AppendText(Environment.NewLine);
rxSerialTextBox.AppendText(Environment.NewLine);
}
//Adds a new character to the text box
rxAllCommsTextBox.AppendText(rxString.Substring(0, 1));
rxSerialTextBox.AppendText(rxString.Substring(0, 1));
rxString = rxString.Substring(1, rxString.Length - 1);
}
}
catch
{
//rxString = "";
}
}
}
答案 0 :(得分:1)
查看SerialPort.DataReceived
事件documentation时,请注意以下备注部分段落:
从SerialPort对象接收数据时,会在辅助线程上引发DataReceived事件。因为此事件是在辅助线程而不是主线程上引发的,所以尝试修改主线程中的某些元素(例如UI元素)可能会引发线程异常。如果有必要修改主窗体或控件中的元素,请使用Invoke发回更改请求,这将在正确的线程上完成工作。
据此,您触摸该事件处理程序内的UI元素(文本框)的代码不正确。文档没有说的是,当你这样做时,行为是未定义的 - 有时它可能工作,另一次挂起,又一次抛出异常。
所以,不要问为什么你的错误代码有时会起作用,你最好集中精力使其正确,只有这样,如果某些东西不起作用,问问为什么并寻求解决方案。
P.S。我不打算解决具体问题如何解决的问题 - 有大量的帖子,解释和如何编组UI线程调用的例子,在这方面你的情况没有什么特别之处。
答案 1 :(得分:0)
你的问题有点令人困惑......
您可以尝试,正确理解,尝试保留您想要分配内存上下文的值,并根据其他类型的迭代分配值。
此时应用程序冻结,显示断点?预期的行为是否有效?
我会尝试配置对象,例如列表,具有各种配置和特定状态,即将列表传递给tabcontrol所需的数量。显然,它需要检查哪些不起作用,为什么不起作用......