在未选中的选项卡中写入文本框

时间:2015-11-17 00:27:36

标签: c# textbox serial-port tabcontrol

我有一个可以在串行,GPIB,USB和以太网上读写的程序。它有一个选项卡,用于与内部显示端口通信的文本框进行通信。其中一个选项卡列为All Comms,该文本框包含来自所有通信方法的数据。我目前正在处理代码的串口部分,我的程序一直在冻结。有一半的时间我运行我的代码它没有问题写入两个选项卡。另一半当它试图写入未选中的选项卡内的文本框时会冻结(通过一次一行代码找到)。

我拉出了标签控件之外的文本框,这解决了冻结问题。当程序冻结时,它不显示错误消息并且不会崩溃,因此没有崩溃报告(让它在周末运行并且它从未完成崩溃)。

我认为我需要选择其他选项卡然后写入它,但为什么代码在我运行它的一半时间内正常工作?

Image of the program

        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 = "";
            }
        }
    }

2 个答案:

答案 0 :(得分:1)

查看SerialPort.DataReceived事件documentation时,请注意以下备注部分段落:

  

从SerialPort对象接收数据时,会在辅助线程上引发DataReceived事件。因为此事件是在辅助线程而不是主线程上引发的,所以尝试修改主线程中的某些元素(例如UI元素)可能会引发线程异常。如果有必要修改主窗体或控件中的元素,请使用Invoke发回更改请求,这将在正确的线程上完成工作。

据此,您触摸该事件处理程序内的UI元素(文本框)的代码不正确。文档没有说的是,当你这样做时,行为是未定义的 - 有时它可能工作,另一次挂起,又一次抛出异常。

所以,不要问为什么你的错误代码有时会起作用,你最好集中精力使其正确,只有这样,如果某些东西不起作用,问问为什么并寻求解决方案。

P.S。我不打算解决具体问题如何解决的问题 - 有大量的帖子,解释和如何编组UI线程调用的例子,在这方面你的情况没有什么特别之处。

答案 1 :(得分:0)

你的问题有点令人困惑......

您可以尝试,正确理解,尝试保留您想要分配内存上下文的值,并根据其他类型的迭代分配值。

此时应用程序冻结,显示断点?预期的行为是否有效?

我会尝试配置对象,例如列表,具有各种配置和特定状态,即将列表传递给tabcontrol所需的数量。显然,它需要检查哪些不起作用,为什么不起作用......