c# richtextbox更新大量数据不卡死的实现方式

 更新时间:2024年04月17日 10:03:54   作者:noworrycd  
这篇文章主要介绍了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的时候加锁。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Unity3D更改默认的脚本编辑器

    Unity3D更改默认的脚本编辑器

    这篇文章简要的说明了如何去修改Unity默认的脚本编辑器,大大提升了灵活性和便捷性,文本有详细的图文介绍,能让你观看的更加清晰,希望对你有所帮助
    2021-06-06
  • C# 运用params修饰符来实现变长参数传递的方法

    C# 运用params修饰符来实现变长参数传递的方法

    一般来说,参数个数都是固定的,定义为集群类型的参数可以实现可变数目参数的目的,但是.NET提供了更灵活的机制来实现可变数目参数,这就是使用params修饰符
    2013-09-09
  • C#连接SQL Server的实现方法

    C#连接SQL Server的实现方法

    这篇文章主要给大家介绍了关于C#连接SQL Server的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-12-12
  • C#实现给DataGrid单元行添加双击事件的方法

    C#实现给DataGrid单元行添加双击事件的方法

    这篇文章主要介绍了C#实现给DataGrid单元行添加双击事件的方法,较为详细的分析了C#给DataGrid单元添加双击事件的步骤及相关实现代码,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • c#实现metro文件压缩解压示例

    c#实现metro文件压缩解压示例

    这篇文章主要介绍了c#实现metro文件压缩解压示例,实现了zip中增加一张新图片、删除文件的方法,需要的朋友可以参考下
    2014-03-03
  • C#在复杂多线程环境下使用读写锁同步写入文件

    C#在复杂多线程环境下使用读写锁同步写入文件

    这篇文章介绍了C#在复杂多线程环境下使用读写锁同步写入文件的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • C#中实现插入、删除Excel分页符的方法

    C#中实现插入、删除Excel分页符的方法

    这篇文章主要给大家介绍了关于在C#中实现插入、删除Excel分页符的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-05-05
  • C#实现单位换算器

    C#实现单位换算器

    这篇文章主要为大家详细介绍了C#实现单位换算器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • C# 元组和值元组的具体使用

    C# 元组和值元组的具体使用

    这篇文章主要介绍了C# 元组和值元组的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • C#中的静态字段double.Epsilon实例详解

    C#中的静态字段double.Epsilon实例详解

    double.Epsilon 是C#中的一个静态字段,表示 double 数据类型的最小可表示的正数值,这篇文章主要介绍了C#中的静态字段double.Epsilon的相关知识,需要的朋友可以参考下
    2024-01-01

最新评论