c# richtextbox更新大量數(shù)據(jù)不卡死的實(shí)現(xiàn)方式
前言
c# 的richtextbox對(duì)讀入幾十萬行大數(shù)據(jù)或者頻繁更新經(jīng)??ㄋ澜缑鎺追昼姟?/p>
終于找到一個(gè)通過子線程更新的方法, 實(shí)際測(cè)試對(duì)于40萬行可以在10秒內(nèi)完成更新, 并且運(yùn)行中界面不卡死可以操作。
一、richtextbox更新方法
richtextbox更新有兩種更新方法:
richtextbox.appendtext() 和 richtextbox.text = richtextbox.text + str。
在子線程中可使用 richtextbox.text = richtextbox.text + str。
為了提高效率, 使用了StringBuilder sb進(jìn)行緩沖, 每maxDisplayline行更新一次richtextbox, 并根據(jù)行數(shù)增加動(dòng)態(tài)調(diào)整了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 = "狀態(tài): " + 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 = "狀態(tài): " + 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 = "異常錯(cuò)誤: " + ex.Message; labelStatus.Update(); });
}
catch { }
}
});
t.IsBackground = true;
t.Start();
Thread.Sleep(33);
while (!stopSign && t != null && t.IsAlive)
{
Application.DoEvents();
Thread.Sleep(3);
}
總結(jié)
richtextbox.text 支持在子線程中直接操作和訪問。
如果需要多線程并發(fā)交互更新,需要在操作sb的時(shí)候加鎖。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C#難點(diǎn)逐個(gè)擊破(3):params數(shù)組參數(shù)
注意,這里的paras全稱是array parameter,也就是數(shù)組參數(shù)。 paras類型參數(shù)主要用于在對(duì)數(shù)組長度未知(可變)的情況下進(jìn)行函數(shù)聲明。2010-02-02
DevExpress SplitContainerControl用法總結(jié)
這篇文章主要介紹了DevExpress SplitContainerControl用法,對(duì)初學(xué)者有一定的參考借鑒價(jià)值,需要的朋友可以參考下2014-08-08

