I'm having trouble working out the correct architecture for the following task. I have a GUI in Windows Forms that contains a ListBox, listing certain architectural layouts. One an item in this list is selected, a custom Control displays an interactive visualization of the selected layout. Drawing of this interactive diagram is a CPU-intensive task, and can take up to a second on my machine.The kind of functionality I'm trying to achieve is that if a user wants to quickly scroll through the layouts in the ListBox (say, holding down the down arrow key), I don't want my computer to sit there thinking about how to draw the layout before it allows the user to do anything else.The obvious answer is, of course, to run the layout calculations in a separate thread. But how do I make that thread return a whole control? How do I make sure I'm not running two layout calculations at once?I'm fairly new to this complex GUI business. So the real question is what is the right architecture to implement something like this? This seems like something people do all the time, but finding any suggestions on how to do it properly is really difficult.
Correct architecture for running and stopping complex tasks in the background
winforms;architecture;user interface
Like Steve Townsend said, the key here is the BackgroundWorker.Since your background worker is the one that draws something on the screen you need to hide the control that is being drawn from view as long as it is not finished. To do that I would draw the content to a hidden control built dynmically and display it only when:the background worker has finished(optionally) the selected entry in the listbox is related to the worker that has finished (to manage concurrency)So when a entry is selected in the listbox:Create a worker related to the entry, the worker should perform his work on a hidden control.Add methods for listening to DoWork and RunWorkerCompleted. The first one for starting your drawing, the second one for when the drawing is over.Attempt to cancel other workers that have not yet finished by calling the CancelAsync on themLaunch the worker by calling RunWorkerAsync()OnRunWorkerCompleted --> Hide the previously displayed control, show the new control the worker has been drawing on. Additionally, if your listbox is not a drop down listbox, you should add a delay(for example  0.2s) to the method listening for changes in the listbox in order to avoid launching workers too fast and when not needed.Hope that helps!