views:

384

answers:

2

I'm writing a screensaver in C# that slowly draws the Sierpinski triangle. I use Thread.Sleep inside the recursive function to slow down the drawing. But I need a way to allow the user to exit by moving the mouse, pressing a key, etc. As my drawing function is called from inside the Paint event handler of the form, mouse and keyboard events are handled only after the whole triangle is drawn, which can take quite a while. How can I force the form to handle events while the recursive function is running? (And how to avoid an infinite loop caused by calling the paint event which calls the drawing function which forces event handling which calls the paint event etc.?)

+2  A: 

You could use a backbuffer bitmap which you compute/draw whenever you want and just show it in the Paint event. The computation could be done in a separate thread.

Dario
+4  A: 

Well you can use Application.DoEvents - but I'm not sure I'd advise it. You can easily end up with re-entrancy problems, particularly in the Paint event.

It sounds like all the real work really needs to be done on the UI thread if you're handling the Paint event - is that right?

An alternative would be to create a Bitmap and draw onto that, instead of using the Paint event handler. You could do this on a background thread, periodically creating a new image, copying the image you've drawn so far onto it, drawing the next layer (or whatever) and then marshalling onto the UI thread to use the image in the UI. This would keep the main UI thread free for event handling. You wouldn't need to handle the Paint event at all - just have a PictureBox which you use to display "the image so far". Don't forget to dispose of old bitmaps when you've finished with them, to avoid memory issues.

Jon Skeet
+1 for the worker approach; I second Jon's advice not to use DoEvents
Marc Gravell