The Render Loop

If you’ve seen the SDK samples for C# or VB.NET, and have looked much at the graphics
samples you may have noticed the render loop, which looks something like this:


Obviously the point of this method is to loop so long as the window is created (which
normally implies the application is still running).  It looks harmless enough,
and is relatively easy to understand, which is why we left it in the SDK, but in reality,
this isn’t the best way you would want to drive your render loop.

Aside from the ‘ugliness’ factor of the loop, the real problem here is the Application.DoEvents
method.  It’s surprising that many people don’t actually realize what’s going
on in this method, and i’d bet you would find even more people that were shocked that
there’s actually an allocation happening in this method.

Let’s look at this simple application:

public class Form1 : System.Windows.Forms.Form
    public Form1()
        for (int i = 0; i < 50000; i++)

    static void Main()

        try{Application.Run(new Form1());}
        catch { }

All this does is show a form, call DoEvents 50,000 times, and exit.  Nothing
fancy at all.  Running this through the CLR
on my machine shows that during the lifetime of this application 6,207,082
bytes of data were allocated.  Comment out the DoEvents and uncomment the Sleep
call, and the application only allocates 406,822 bytes on my machine.  Doing
the math, that averages out to ~116 bytes allocated per call to DoEvents. 

If you’re running a high frequency render loop, running at say, 1000 frames per second,
that’s 100k of data you’re allocating per second.  This will cause quicker gen0
collections, which can needlessly promote your own short lived objects to gen1, or

Morale of the story.  Just because it looks easy, doesn’t mean it’s the right

Comments (14)

  1. Shaigan says:

    Hi, I just wanted to know what if the best pratice for the main render loop ? Is it better to call the peekmessage win32 function directly into the main render loop ?

  2. confuzuled says:

    Hey — aren’t ya going to answer the question? I mean, its one thing to point out that the examples suck, but, you could at least point people in the right direction… what is a better way to handle that loop?

  3. Chris says:

    Maybe use the paint events to render, or setup a timer?

  4. Mike Sax says:

    Hi Tom,

    This is very true in a background thread, but what if you have a single-threaded application that you want to keep responsive while you’re inside your loop… with Sleep() calls, the app will just appear frozen.

    I’m not clear why DoEvents would allocate memory… is it really DoEvents allocating the memory, or is it the code that gets an opportunity to run due to the call to DoEvents (ie: the message pump gets processed) that is doing this?

    — Mike

  5. Mikel Rice says:

    Hey Tom, it would have been helpful if you mentioned this in your book "Managed DirectX 9 Graphics and Game Programming" as it sent up major red flags in my C++/MFC trained mind! Invalidating in an OnPaint runs counter to everything I’ve learned! 🙂

    I have heard people comment on using the OnIdle for rendering as opposed to DoEvents or OnPaint. Any opinion on that?

  6. I just noticed that the Aplication.DoEvents method was alocating memory. It seems strange that this would happen because in the Microsoft DirectX tutorials, this is what they use. I read somewhere that this may evetually get cleaned up automatically by .NET when resources get low, but I haven’t tested it as I have 1gig ram.

    I’ve tried running a render loop with the Application.Idle event, but that’s no good because it is only fired once just before the app is about to go into the idle state, then it just sits there while idle.

    I may try using a timer to call the loop or see if I can work out how to do a custom event that fires continuously whenever the application is in the idle state, otherwise I’ll just stick with Application.DoEvents and blame Microsoft for the extraneous memory use.