To optimize performance and keep animation smooth you need two things:
1) Keep using double buffering;
2) Do not use
Refresh
(of course), but don't use Invalidate() as well: use
Invalidate
with parameters: invalidate only a part of your scene.
Oh, yes, if you can -- move to WPF -- much better for animation (of different sorts, not only using available animation-related library classes).
As Marcus added a note on the use of thread (
BackgroundWorker
or explicitly created thread) -- thank you Markus -- I want to add a note.
The body of the animation thread should do two things: it should periodically update the data used in Paint event and then perform invalidation. Important to remember: Invalidate method should be called on UI thread, so the animation thread should perform inter-thread invocation:
MyCanvasControl.Invoke(new System.Action<Control>(
(Control control) => {
control.Invalidate(sceneSubset);
}), MyCanvasControl);
Note, that is the rendering data is updated due to the UI user, invalidation should be done immediately on UI thread through a direct call to
Invalidate
, no use of any thread synchronization primitive needed:
Invoke
takes care of it.
Finally, it's the best to avoid using of the timer.