Click here to Skip to main content
15,867,835 members
Articles / Desktop Programming / WPF

Application.DoEvents in WPF

Rate me:
Please Sign up or sign in to vote.
4.83/5 (4 votes)
20 Oct 20112 min read 58K   4   3
Implementing Application.DoEvents in WPF.

Recently I’ve been trying to make some thumbnail generation code synchronous. I’m trying to grab the first frame from a Shockwave Flash (SWF) or Flash Video (FLV) file and save it as a thumbnail, but in order to do that, I needed to create a window to host an ActiveX control that renders the Flash file so that I can then use RenderTargetBitmap to grab a frame.

The code sits inside a handler for the ContentRendered event of the window and is initialised like this:

C#
1:  public bool CreateThumbnail(string sourcePath, string targetPath)
   2:  {
   3:      // NOTE: Loads of code missed for brevity.
   4:      ManualResetEvent waitHandle = new ManualResetEvent(false);
   5:      bool generated = false;
   6:   
   7:      var win = new Window()
   8:      {
   9:          AllowsTransparency = true,
  10:          Opacity = 0.0,
  11:          Left = 0,
  12:          Top = 0,
  13:          SizeToContent = SizeToContent.WidthAndHeight,
  14:          ShowInTaskbar = false,
  15:          WindowStyle = WindowStyle.None
  16:      };
  17:      win.ContentRendered += (sender, e) =>
  18:      {
  19:          // Use RenderTargetBitmap to get the frame and save it.
  20:          generated = true;
  21:          waitHandle.Set();
  22:      }
  23:   
  24:      win.Show();
  25:      waitHandle.WaitOne(5000);
  26:      return generated;
  27:  }

The problem is that the ContentRendered event doesn’t fire until after the WaitOne call on the ManualResetEvent, effectively meaning that thumbnail generation fails all the time. Basically, the UI thread is blocked waiting for the wait handle to be signaled, so it doesn’t get round to rendering the window until after this method has called.

For VB programmers out there, you may be thinking that you simply call Application.DoEvents() to free up the message loop and unfortunately WPF doesn’t provide the same API. However, there is a way to do this in WPF. By pushing a nested message loop, we can cause this nested message loop to be processed immediately, allowing the window’s content to be rendered and our thumbnail to be generated. I wouldn’t recommend using nested message loops and neither would many other people, but in this case, it works for me. All I needed to do was to add the following line of code between the win.Show() call and the waitHandle.WaitOne(5000) call above:

C#
Application.Current.Dispatcher.Invoke(
    DispatcherPriority.Background, 
    new ThreadStart(delegate { }));

Thanks to Zhou Young’s post for the simplest implementation of DoEvents in WPF that I’ve seen. As you can see, he’s put it in his Application class, but personally I think that’s just encouraging you to use this approach and in most cases, I think there’s a better solution for you.

This article was originally posted at http://feeds2.feedburner.com/cloudstore

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Bugsubj Pin
shnaider1117-Jul-17 2:10
shnaider1117-Jul-17 2:10 
QuestionUsing's Pin
User 917861223-Apr-14 1:35
User 917861223-Apr-14 1:35 
SuggestionFound another implementation on msdn Pin
Filip D'haene28-Oct-11 11:31
Filip D'haene28-Oct-11 11:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.