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

Writing to textbox inside an unselected tab

我有一个可以在串口、GPIB、USB 和以太网上读写的程序。它有一个用于每种通信方法的选项卡,里面有一个文本框,显示端口上的通信。其中一个选项卡列为所有通信,该文本框包含来自所有通信方法的数据。我目前正在处理代码的串行端口部分,但我的程序一直处于冻结状态。一半时间我 运行 我的代码在写入两个选项卡时都没有问题。另一半在尝试写入未 selected 的选项卡内的文本框时冻结(通过一次一行地逐步执行代码找到)。

我将文本框拉到选项卡控件之外,这解决了冻结问题。当程序冻结时,它不会显示错误消息,也不会崩溃,因此没有崩溃报告(在 运行 周末离开它,它从未完成崩溃)。

我认为我需要 select 另一个选项卡然后写入它,但为什么代码在我 运行 它的一半时间里能正常工作?

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

你的问题有点混乱...

你可以试试,理解正确,尽量保留你要赋值的内存上下文,根据另一种迭代类型赋值。

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

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

快速查看 SerialPort.DataReceived 事件 documentation 会注意到以下 备注 部分段落:

The DataReceived event is raised on a secondary thread when data is received from the SerialPort object. Because this event is raised on a secondary thread, and not the main thread, attempting to modify some elements in the main thread, such as UI elements, could raise a threading exception. If it is necessary to modify elements in the main Form or Control, post change requests back using Invoke, which will do the work on the proper thread.

据此,您在事件处理程序中涉及 UI 元素(文本框)的代码是不正确的。文档没有说明的是,当您这样做时,行为是未定义的——有时它可能会起作用,有时会挂起,有时会抛出异常。

因此,与其问为什么您的错误代码有时会起作用,不如集中精力使其正确,只有在某些地方不起作用时,才问为什么并寻求解决方案。

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