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#數(shù)據(jù)綁定之向查詢中添加參數(shù)(.Net連接外部數(shù)據(jù)庫)
本實(shí)例主要練習(xí)了ADO.Net連接到外部數(shù)據(jù)庫的基礎(chǔ)上,向查詢中添加參數(shù)。使用的是ACCESS數(shù)據(jù)庫2014-04-04C#中自定義高精度Timer定時(shí)器的實(shí)例教程
這篇文章主要介紹了C#中自定義高精度Timer定時(shí)器的實(shí)例教程,多線程的Timer編寫需要注意線程安全的問題,需要的朋友可以參考下2016-04-04C#實(shí)現(xiàn)塊狀鏈表的項(xiàng)目實(shí)踐
這篇文章主要介紹了C#實(shí)現(xiàn)塊狀鏈表的項(xiàng)目實(shí)踐,通過定義塊和鏈表類,利用塊內(nèi)元素引用實(shí)現(xiàn)塊與塊之間的鏈接關(guān)系,從而實(shí)現(xiàn)對(duì)塊狀鏈表的遍歷、插入和刪除等操作,感興趣的可以了解一下2023-11-11C#操作DataGridView獲取或設(shè)置當(dāng)前單元格的內(nèi)容
這篇文章介紹了C#操作DataGridView獲取或設(shè)置當(dāng)前單元格的內(nèi)容,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02C#面向?qū)ο缶幊讨幸蕾嚪崔D(zhuǎn)原則的示例詳解
在面向?qū)ο缶幊讨?,SOLID?是五個(gè)設(shè)計(jì)原則的首字母縮寫,旨在使軟件設(shè)計(jì)更易于理解、靈活和可維護(hù)。本文將通過實(shí)例詳細(xì)講講C#面向?qū)ο缶幊讨幸蕾嚪崔D(zhuǎn)原則,需要的可以參考一下2022-07-07