Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DoEvents: Dispatcher.Invoke vs. PushFrame

Tags:

wpf

dispatcher

Recently I found a method that performs all pending messages in the dispatcher queue until a specified priority. I already had such code before, but they use completely different methods. Here's both of them:

The PushFrame way:

/// <summary>
/// Enters the message loop to process all pending messages down to the specified
/// priority. This method returns after all messages have been processed.
/// </summary>
/// <param name="priority">Minimum priority of the messages to process.</param>
public static void DoEvents(
    DispatcherPriority priority = DispatcherPriority.Background)
{
    DispatcherFrame frame = new DispatcherFrame();
    Dispatcher.CurrentDispatcher.BeginInvoke(
        priority,
        new DispatcherOperationCallback(ExitFrame), frame);
    Dispatcher.PushFrame(frame);
}

private static object ExitFrame(object f)
{
    ((DispatcherFrame) f).Continue = false;
    return null;
}

Source: MSDN Library

The blocking Invoke way:

private static Action EmptyDelegate = delegate { };

/// <summary>
/// Processes all pending messages down to the specified priority.
/// This method returns after all messages have been processed.
/// </summary>
/// <param name="priority">Minimum priority of the messages to process.</param>
public static void DoEvents2(
    DispatcherPriority priority = DispatcherPriority.Background)
{
    Dispatcher.CurrentDispatcher.Invoke(EmptyDelegate, priority);
}

Source: Blog

Which is better and are there any functional differences between the two solutions?

Update: Here's number two with the delegate inlined, as in number one, making it even shorter:

/// <summary>
/// Processes all pending messages down to the specified priority.
/// This method returns after all messages have been processed.
/// </summary>
/// <param name="priority">Minimum priority of the messages to process.</param>
public static void DoEvents2(
    DispatcherPriority priority = DispatcherPriority.Background)
{
    Dispatcher.CurrentDispatcher.Invoke(new Action(delegate { }), priority);
}
like image 896
ygoe Avatar asked Aug 22 '14 07:08

ygoe


1 Answers

You sort of answered your own question. It doesn't matter much which you pick since both do the same in the background.

Both run into this:

While (dispatcherFrame.Continue)
{
  Dispatcher.GetMessage();
  Dispatcher.TranslateAndDispatch();
}

However PushFrame is a bit nicer since you do not need to create empty delegate.

like image 96
dev hedgehog Avatar answered Oct 11 '22 13:10

dev hedgehog