1. 程式人生 > >雙緩衝解決高頻率重新整理介面閃爍問題(C#)

雙緩衝解決高頻率重新整理介面閃爍問題(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來控制定時器是否執行和讀取.