c# richtextbox更新大量数据不卡死的办法

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

c# 的richtextbox对读入几十万行大数据或者频繁更新经常卡死界面几分钟。
终于找到一个通过子线程更新的方法, 实际测试对于40万行可以在10秒内完成更新, 并且运行中界面不卡死可以操作。

一、richtextbox更新方法

richtextbox更新有两种更新方法:richtextbox.appendtext() 和 richtextbox.text = richtextbox.text + str。
在子线程中可使用 richtextbox.text = richtextbox.text + str。

为了提高效率, 使用了StringBuilder sb进行缓冲, 每maxDisplayline行更新一次richtextbox, 并根据行数增加动态调整了maxDisplayline的大小。

二、使用步骤

代码如下(核心代码):

        maxDisplayline = 1 * 1000; // 1000行
       StringBuilder sb = new StringBuilder();
        Stopwatch swGlobal = new Stopwatch();
        string[] sblineslist = in_str.Split(new char[] { '\n' }); // instr 为输入字符串,可以是文件读入的
        // static readonly object lockSb = new object();

        richTextBoxDisplay.Focus();
        sb.Clear();
        Thread.Sleep(1);

        
        swGlobal.Reset(); swGlobal.Start();

        Thread t = new Thread((ThreadStart)delegate
          {
              try
              {
                  for (int i = 0; i < sblineslist.Length; i++)
                  {
                      if (stopSign)
                      {
                          return;
                      }

					// lock(lockSb)
                      sb.Append(sblineslist[i] + "\n");

                      if (i > 0 && i % maxDisplayline == 0)
                      {
                          this.Invoke((EventHandler)delegate { labelStatus.Text = "状态: " + count + "/" + manualSyncFilesFullname.Count + " " + runsecond + "s -> " + (i + 1) 
                              + " Act/Rest: " + swGlobal.ElapsedMilliseconds/1000 + "/" + (int)(1.0 * swGlobal.ElapsedMilliseconds * (sblineslist.Length - (i+1)) /(i+1) /1000) + "s";
                              labelStatus.Update(); });

                          if (sb.Length > 0)
                          {
          						// lock(lockSb)
                              this.richTextBoxDisplay.Text = this.richTextBoxDisplay.Text + sb.ToString();
                              sb.Clear();
                          }

                          maxDisplayline = maxDisplayline * ((int)Math.Sqrt(i/ maxDisplayline));
                      }
                  }

                  if (sb.Length > 0)
                  {
   						// lock(lockSb)
                      this.richTextBoxDisplay.Text = this.richTextBoxDisplay.Text + sb.ToString();
                      sb.Clear();
                  }
                  this.Invoke((EventHandler)delegate { labelStatus.Text = "状态: " + count + "/" + manualSyncFilesFullname.Count + " " + runsecond + "s -> " + sblineslist.Length.ToString()
                      +" Act: " + swGlobal.ElapsedMilliseconds / 1000 + "s";
                      labelStatus.Update(); });
              }
              catch (Exception ex)
              {
                  try
                  {
                      stopSign = true;
                      this.Invoke((EventHandler)delegate { labelStatus.Text = "异常错误: " + ex.Message; labelStatus.Update(); });
                  }
                  catch { }
              }
        });

        t.IsBackground = true;
        t.Start();
        Thread.Sleep(33);

        while (!stopSign && t != null && t.IsAlive)
        {
            Application.DoEvents();
            Thread.Sleep(3);
        }

总结

richtextbox.text 支持在子线程中直接操作和访问。
如果需要多线程并发交互更新,需要在操作sb的时候加锁。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值