相信很多寫WinForm的人也遇到要局部更新UI來避免畫面閃爍,這不是甚麼新的東西。只是最近在寫更複雜的局部更新是遇到一些問題,畫面的更新有延誤,所以研究了一下,得出下面的結論。
以上是我自己的見解,並不見得正確,正確版本請參考MSDN。
相信很多寫WinForm的人也遇到要局部更新UI來避免畫面閃爍,這不是甚麼新的東西。只是最近在寫更複雜的局部更新是遇到一些問題,畫面的更新有延誤,所以研究了一下,得出下面的結論。
一般要局部更新,要先檢查目前的執行緒是worker還是UI,一般會這樣做
private void GuiUpdate() { if (Control.InvokeRequired) { Control.Invoke(GuiUpdate, new object[] { sender, args }); } else { //do your Control update here. } }
網路上很多這樣的sample,但其實這樣做並不夠,因為那個delegate送出去後,元件會在系統覺得需要重畫時 才重畫,有點像GC回收Memory,如果需要即時更新,需要做下面的動作。
{ //do your control update here. Control.Invalidate(); Control.Update(); }
Invalidate方法會告訴系統該元件需要重畫,Update方法會強迫發動重畫。為甚麼這麼麻煩呢?其實這裡的原理 有點像SQL的Transaction,也就是bulk或者叫batch。他們之間的關係可以看下面的圖。
所以可以累積一定數量的Invalid元件,再選擇一個時間點全部重畫,以提升效能。 以上是我自己的見解,並不見得正確,正確版本請參考MSDN。