雙緩衝解決高頻率重新整理介面閃爍問題(C#)
專案背景:
介面包括幾百個終端模擬物件,為自定義多變形控制元件,在1/s次與實際終端取樣通訊頻率下,要求軟體實時更新,實際終端有執行、停止、暫停、工作結束、斷電、告警等多種實時模式,軟體介面需要將各種模式用不同背景顏色表示出來,並且將電壓、電流、狀態等引數顯示在模擬終端。
面臨問題: 介面重新整理閃爍,讓使用者視覺感覺差!
●初期方法:
採用單純開啟雙緩衝
this.SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw |
ControlStyles.AllPaintingInWmPaint, true);
根本無法解決問題
●具體解決辦法
a 原理部分:
1 首先通訊、業務處理、介面執行緒序分開,通訊部分可開啟多個子執行緒後臺執行,取樣資料、狀態等。
2業務處理部分的執行緒負責對取樣資料的分析和儲存,以及根據狀態對多個通訊執行緒進行啟動和停止,也叫就是管理執行緒的執行緒
3 介面執行緒只負責更新介面狀態和與響應使用者互動。幾百個模擬終端全屏都無法顯示完全,採取分組顯示更新,這樣重新整理頻率明顯下降。
本專案中採用100個模擬終端/組顯示,每個模擬終端定時1S重新整理介面同時讀取記憶體資料。
b實現部分:
1 系統主程式開啟雙緩衝
2 在控制元件內部,在OnPaint方法中優化雙緩衝
this.SetStyle(ControlStyles.ResizeRedraw | ControlStyles.Opaque, true);
3 每個控制元件必須採取記憶體物件繪製,這樣可以解決40%左右閃爍問題。一個控制元件物件對應一個模擬終端
控制元件內部程式碼實現:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
this.SetStyle(ControlStyles.ResizeRedraw | ControlStyles.Opaque, true); //優化雙緩衝
Graphics g = e.Graphics;
Bitmap localBitmap = new Bitmap(ClientRectangle.Width, ClientRectangle.Height);//建立記憶體物件
Graphics bitmapGraphics = Graphics.FromImage(localBitmap);
bitmapGraphics.SmoothingMode = SmoothingMode.AntiAlias; //解決影象不平滑問題(反鋸齒)
bitmapGraphics.Clear(BackColor);
DrawMyObject(bitmapGraphics); // DrawMyObject 為自定義方法,繪製多邊型過程
g.DrawImage(localBitmap, 0, 0);
bitmapGraphics.Dispose();//釋放資源
localBitmap.Dispose();//釋放資源
g.Dispose();
}
OnPaint方法只涉及對重新整理的處理,具體如何觸發重繪方法等需要實際專案中具體分析和把握。
4 控制元件自帶定時器定時更新自身狀態,附加一個狀態量關聯visible來控制定時器是否執行和讀取.