【问题标题】:UI becomes unresponsive when RichTextBox is pumped with huge data [duplicate]当 RichTextBox 被大量数据抽取时,UI 变得无响应 [重复]
【发布时间】:2019-11-13 18:52:18
【问题描述】:

我正在开发一个 GUI,用户可以在其中连接到服务器并读取数据。数据需要显示在 GUI 上。为此,我使用了 TabControl,其 ContentTemplate 设置为 RichTextBox。

当用户点击连接按钮时,UI 连接到 TCP 服务器。在这里,我生成了一个从服务器读取数据的新线程。然而,当大量数据被泵送到 RTB 后,UI 变得无响应。我无法在屏幕内移动应用程序。

有什么方法可以让我动态删除旧数据(新数据在下面附加),这样 RTB 就不会加载太多并且 UI 应该可以正常工作。 此外,该应用程序在任务管理器中的进程下使用多达 80 个 CPU

private void BtnConnect_Click(object sender, RoutedEventArgs e)
        {
            //connect
            TCPClientClass tcpClient = TCPConnHandler.ConnectToService(tbIPAddress.Text);
            if (tcpClient != null)
            {
                MessageBox.Show("Connected to " + tbIPAddress.Text);
                //open new tab
                var item = MainWindowVMObj.AddTabItem();

                Thread thTabControl = new Thread(() =>
                {
                    while (tcpClient.Connected)
                    {
                        String str = tcpClient.GetDataFromServer();
                        if (!String.IsNullOrEmpty(str))
                            tabControl1.Dispatcher.BeginInvoke((Action)(() => item.Content += str));
                        Thread.Sleep(200);
                    }
                    //item.Dispatcher.BeginInvoke
                });

                thTabControl.Start();
            }
        }

【问题讨论】:

  • 您忽略了response,这是一个包含接收到的字节数的整数。阅读文档。
  • TCP 被分割成最大大小约为 1500 字节的数据报。路由器和服务器可以拆分和重组数据报。在 TCP 连接关闭之前,您不会收到 EOF。您应该使用处理将数据报打包成消息的网络流,以便您知道何时收到消息结束(您的数据结束)。 c# 中的字符串是每个字符可以是一个或两个字节的类。因此,如果两个字节字符的对齐方式未对齐,则字符串看起来会出现乱码。
  • @jdweng NetworkStream 完全不对消息和消息的结尾一无所知; NetworkStream 纯粹StreamSocket 的抽象;它不添加任何框架;至于strings:这取决于编码;在 OP 的情况下,他们使用 ASCII,所以:单字节
  • 为什么我的 UI 变得没有响应。我可以在动态添加新数据的同时删除 RTB 中的旧数据吗?我是 C# 和 WPF 的新手。任何线索将不胜感激。提前致谢

标签: c# wpf richtextbox


【解决方案1】:

ReadReadAsync 返回一个整数,告诉您他们收到了多少;如果该值为非正数,则表示已到达数据末尾(接收套接字关闭等);对于正数,您应该只查看接收缓冲区中的第一个(多个)字节。

请注意,此不一定包含完整的消息; TCP是流协议,不是消息协议;您不能保证一次性获得所有内容,这就是为什么在 TCP 上发送多条消息时需要某种“框架”层,以便您知道每条消息的结束位置。另请注意,使用多字节编码发送文本时,您可以接收部分字符,即可以在 3 个 不同 调用 Read 中接收 3 个字节字符 - 因此您通常需要缓冲帧直到你知道你有一个完整的框架。

对于字符串数据,一种常见的框架技术是“行尾”,即查找\r\n\r\n\n\r(尽管可以使用其他选项)。对于二进制数据,长度前缀是规范。

【讨论】:

  • 感谢您的信息。我会检查同样的。
猜你喜欢
  • 2013-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-17
  • 2019-01-27
  • 1970-01-01
相关资源
最近更新 更多