I am currently working on a C# winforms graphing application. To get right to the point, the Paint event handler for my graphing control has to plot thousands of points which can take several seconds. During this time the application is frozen. My goal is the following: if the user changed what data to be plotted while the older data is being plotted then it would stop in the middle of drawing the older data and start drawing the new the data. What is the proper way to do this or is this something else I am total missing? I tried to make my question as clear as possible.
Asked
Active
Viewed 179 times
0
-
Look at putting your draw event inside a `Task.Run`, pass through a `CancellationToken` and check if the task has been cancelled within your draw loop. If the user updates the data, then fire your cancellation token and redraw with the new data. The task will stop your application from locking up. – Malcor May 29 '18 at 14:09
-
2It would be an idea to (assuming you use images/bitmaps) draw the image on a different thread, when it's done, you send it to the main thread and add it to your picturebox – H.J. Meijer May 29 '18 at 14:09
-
1You can double-buffer by creating a separate bitmap the same size as the display and drawing into that from a background thread, and then use `Graphics.DrawImage()` to draw the image (from the UI thread) when it's done. (It's a little more fiddly than that, but that's the gist of it.) – Matthew Watson May 29 '18 at 14:09
-
2You can cache the older (1000s) points in a bitmap and only plot the latest (100s) ones. And if really necessary you can even prepare the bitmap in a spearate thread. – TaW May 29 '18 at 14:56
-
@TaW That sounds like it would solve my a lot of my problems. Thank you! If not to much trouble could you post a simple example on how to create a bitmap image and then update the UI Thread with it? – Robo Maklen May 29 '18 at 15:16
-
[Here](https://stackoverflow.com/questions/31104272/keeping-graphics-unaltered-when-tabpage-changes/31104683#31104683) is a tiny code example on how to draw intot a Bitmap which you can display on a control. But for a more specific code example one would need to know a lot more about your case. So you have the data prepared; where and how are they stored? When and how and how often do they change? What exactly is the user interaction? What does 'drawing a point' actually mean? Will a separate thread actually be necessary?..... – TaW May 29 '18 at 15:26
1 Answers
1
The answer to you question lies in double buffering. You don't need to know all the details about double buffering to use it. Simply set the property to true like below to enable it within a control.
MyGraphPanelControl.DoubleBuffered = true;
The obvious draw back is memory usage but it will greatly increase the "speed" of things drawn on the panel. Like a lot of things in Computer Science, you trade memory for speed and visa versa.
Also, reading this from Microsoft will give you more insight in how to use Double Buffering.

Cabbage Champion
- 1,193
- 1
- 6
- 21
-
Enabling double-buffering isn't going to do anything to prevent the UI thread from being blocked while rendering occurs. It just means that the result of rendering won't be visible until the entire render operation has completed. – Peter Duniho Jul 03 '19 at 01:10