Table of Contents
Optimizing for Performance
Setting Multiple Properties at Runtime
By default, a control is may be redrawn any time one of its properties changes. While this may be convenient much of the time, it can be quite inefficient if several properties need to be updated together because the control could potentially trigger a redraw after each property change.
Illustrating the Problem
Imagine you have a lamp that you'd like to “turn on” in response to a digital input on a PLC. However, in addition to “turning on”, you also want to update its Text and Font properties at runtime. It may be tempting to implement this operation somewhat like the following:
void UpdateLamp(bool isOn) { // Lamp may redraw here... lamp.IsOn = isOn; // ...here... lamp.Text = lamp.IsOn ? "ON" : "OFF"; // ...and here... lamp.Font = new Font(Font.Name, Font.Size, lamp.IsOn ? FontStyle.Bold : FontStyle.Regular); }
The code above could potentially redraw the lamp 3 times, when only one draw is needed. While it may not be noticeable with a single control, the effect becomes more apparent with the addition of more controls.
The Solution
To remedy the problem, the SuspendDraw method can be use to suspend the control's drawing operations until the control's state is fully updated. Then the ResumeDraw method can be used to resume and initiate the control's drawing operations.
void UpdateLamp(bool isOn) { lamp.SuspendDraw(); // lamp will not redraw here lamp.IsOn = isOn; // ...or here... lamp.Text = lamp.IsOn ? "ON" : "OFF"; // ...or here... lamp.Font = new Font(Font.Name, Font.Size, lamp.IsOn ? FontStyle.Bold : FontStyle.Regular); // lamp will redraw here lamp.ResumeDraw(); }
In addition to making the display appear less jittery, this method should also improve performance when multiple controls need to be updated simultaneously.
Please note that every call to SuspendDraw increments a counter, and every call to ResumeDraw decrements that counter. Both methods return this count when called. ResumeDraw will only initiate the control's drawing routines when the count reaches 0. In other words, for every call to SuspendDraw there must eventually be a matching call to ResumeDraw for the drawing to be initiated.
