Thursday, April 28, 2011

WPF: Dispatcher - Understanding Frames

Over the last couple of posts, I covered the process through which an application establishes its primary Dispatcher object. I now want to examine how this Dispatcher actually runs. Based on previous experience, I know the Dispatcher sits in a loop dequeuing work and executing it, but how is that loop governed and what types are in play?


We know from previous exploration on this blog that Application.Run() ultimately calls Dispatcher.Run() to "get the loop going". So, is there a loop in that Run() method? Not precisely...
// System.Windows.Threading.Dispatcher
[SecurityCritical]
public static void Run()
{
    Dispatcher.PushFrame(new DispatcherFrame());
}



MSDN says that a DispatcherFrame "[r]epresents an execution loop in the Dispatcher". When I first read this, I jumped to the conclusion that the DispatcherFrame must own the loop itself, expecting that it would define a method with the magic loop in it, but this is not the case. The DispatcherFrame "represents" the loop and provides governing control of the loop, but there is nothing executable about it:
namespace System.Windows.Threading
{
    public class DispatcherFrame : DispatcherObject
    {
        private bool _exitWhenRequested;
        private bool _continue;

        public DispatcherFrame() : this(true) {}
        public DispatcherFrame(bool exitWhenRequested{ ... }

        public bool Continue { getset; }    }
}


There are two governing controls to a DispatcherFrame. At construction time, you can specify whether your frame will "play nice" and exit when the Dispatcher wants to shutdown or whether it will wait for its own termination condition. The Continue property is used to control the loop represented by the DispatcherFrame, but we still haven't discovered where that loop is!

Dispatcher.Run() calls Dispatcher.PushFrame() to push a "default" DispatcherFrame into play. Let's see what this does:
// System.Windows.Threading.Dispatcher
public static void PushFrame(DispatcherFrame frame)
{
    // lots of error checking... not important to our discussion
    Dispatcher currentDispatcher = Dispatcher.CurrentDispatcher;

    currentDispatcher.PushFrameImpl(frame);
}



private void PushFrameImpl(DispatcherFrame frame)
{
    MSG mSG = default(MSG);
    this._frameDepth++;

    try
    {
        // synchronization... not important to our discussion
        try
        {
            // more synchronization... not important to our discussion

           while (frame.Continue && this.GetMessage(ref mSG, IntPtr.Zero, 0, 0)) // aha!
            {
                this.TranslateAndDispatchMessage(ref mSG);
            }


            if (this._frameDepth == 1 && this._hasShutdownStarted)
            {
                this.ShutdownImpl();
            }
        }
        finally
        {

            // even more synchronization... not important to our discussion
        }
    }
    finally
    {
        this._frameDepth--;
        if (this._frameDepth == 0this._exitAllFrames = false;
    }
}



Now we're getting somewhere! When we call PushFrame(), we will get pulled into a while loop that won't exit until the frame no longer needs to continue or until our message source is cut off. In a typical application, we will sit in that loop and process Windows messages until the application wants to shutdown.

This first call to PushFrame() gets everything going, but we can see from the decompiled source that the Dispatcher expects that multiple frames can come into play over time. The most common case for this is when we are in the middle of dispatching a long-running/blocking operation and need to force the Dispatcher to process other items off its queue (to keep the UI responsive, perhaps). We can't really return from the original operation, so we push another frame to get us back to processing the queue in a nested while loop. The documentation for DispatcherFrame on MSDN illustrates this "DoEvents" case and Kent Boogaart takes that example to the next level.

Kent proposed an alternate solution to the DoEvents problem that doesn't seem to require any DispatcherFrames:
public static void DoEvents(this Application application)
{
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background,
new VoidHandler(() => { }));
}

private delegate void VoidHandler();

I thought this was quite curious. We're sitting on the dispatcher's thread and we tell our dispatcher to queue up a do-nothing, background-priority operation and wait for it to complete. I can understand that all higher priority operations in the queue will get worked off before the one we're inserting, but how in the world can the dispatcher get back to processing the queue when we're sitting on its thread waiting for something to happen?


The Dispatcher class has an internal InvokeImpl() method that all flavors of Invoke() ultimately call. The following piece of code in InvokeImpl() forces the wait to happen:


var dispatcherOperation = this.BeginInvokeImpl(priority, method, args, numArgs);
if (dispatcherOperation !null)
{
    dispatcherOperation.Wait(timeout);

    // operation status checks... not important to our discussion
}


On the surface, this is exactly what we would expect. Any Invoke() call can be performed in terms of a BeginInvoke() and DispatcherOperation manipulation. The BeginInvokeImpl() call will get our do-nothing operation on the queue, but where does the queue get processed? Let's see what happens during the call to DispatcherOperation.Wait():
// System.Windows.Threading.DispatcherOperation
public DispatcherOperationStatus Wait(TimeSpan timeout)
{
    if ((this._status == DispatcherOperationStatus.Pending || this._status == DispatcherOperationStatus.Executing)

        && timeout.TotalMilliseconds !0.0)
    {
        if (this._dispatcher.Thread == Thread.CurrentThread)
        {

            // error check... not important to our discussion

            var frame = new DispatcherOperation.DispatcherOperationFrame(this, timeout); // ok then!
            Dispatcher.PushFrame(frame);
        }
        else
        {
             var dispatcherOperationEvent = new DispatcherOperation.DispatcherOperationEvent(this, timeout);
            dispatcherOperationEvent.WaitOne();
        }
    }
    return this._status;
}


This method needs to handle two separate cases:
  • If we are waiting for a DispatcherOperation from a different thread to complete, we need to use something akin to a ManualResetEvent to signal completion across the thread boundary.
  • If we are on the same thread as the operation's dispatcher, we need to call Dispatcher.PushFrame() to get back to servicing the queue.
DispatcherOperation.DispatcherOperationFrame derives from DispatcherFrame and will continue to loop while the operation of interest hasn't completed or aborted. Once the do-nothing operation signals one of these conditions, the inner frame will exit and our Invoke() call will return. The outer frame will take over at that point and keep the loop going.

There is no magic here. Kent's shorter solution is more elegant because it expresses the DoEvents problem in terms of Invoke semantics -- which are easier to understand than frame semantics -- but rest assured that DispatcherFrames are still in play.

[Swedish House Mafia: Miami 2 Ibiza -- YouTube]

References

Wednesday, April 27, 2011

WPF: DispatcherObject - Anatomy

In my last post, I was a bit surprised to see how DispatcherObject is implemented behind-the-scenes. Since this class is at the top of the WPF "Spine", I want to take time to understand all aspects of it, giving it the same level of attention I gave Object when I first started programming in .NET over ten years ago.

ILSpy gives us the following view of DispatcherObject, disclosing little more than the official MSDN documentation for this class:

using MS.Internal.WindowsBase;
using System;
using System.ComponentModel;
using System.Runtime;
namespace System.Windows.Threading
{
    public abstract class DispatcherObject
    {
        private Dispatcher _dispatcher;
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        public Dispatcher Dispatcher...
        [FriendAccessAllowed]
        internal void DetachFromDispatcher()... ???
        [EditorBrowsable(EditorBrowsableState.Never)]
        public bool CheckAccess()...
        [EditorBrowsable(EditorBrowsableState.Never)]
        public void VerifyAccess()...
        protected DispatcherObject()...
    }
}



First and foremost, we must acknowledge that DispatcherObject is abstract, so no direct instantiation of this class is possible. Naturally, this means the constructor would be protected.

From my last post, we saw that the constructor initializes the _dispatcher instance field by calling Dispatcher.CurrentDispatcher. Given my prior experience with the Dispatcher class, I would expect DispatcherObject's CheckAccess() and VerifyAccess() methods to leverage _dispatcher in their implementations, and indeed they do with one minor surprise:
// System.Windows.Threading.DispatcherObject
protected DispatcherObject()
{
    this._dispatcher = Dispatcher.CurrentDispatcher;

}

[EditorBrowsable(EditorBrowsableState.Advanced)]
public Dispatcher Dispatcher
{
    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    get
    {
        return this._dispatcher;
    }

}

public bool CheckAccess()
{
    bool result = true;
    Dispatcher dispatcher = this._dispatcher;
    if (dispatcher !null)
    {
        result = dispatcher.CheckAccess();
    }
    return result;
}

[EditorBrowsable(EditorBrowsableState.Never)]
public void VerifyAccess()
{
    Dispatcher dispatcher = this._dispatcher;
    if (dispatcher !null)
    {
        dispatcher.VerifyAccess();
    }
}


The constructor gives us a reference to the Dispatcher for this thread, but CheckAccess() and VerifyAccess() both check to see if _dispatcher is null? I guess we should have expected this since _dispatcher is not declared readonly.

DetachFromDispatcher() undoes the work done by the constructor. The effect is permanent, since there is no way to set the value of _dispatcher again after this method is called:

[FriendAccessAllowed]
internal void DetachFromDispatcher()
{
    this._dispatcher = null;
}


Why do we need this? Almost all classes in the DispatcherObject WPF hierarchy want to have thread affinity, except for objects that derive from Freezable. When you tell a Freezeable object to Freeze(), it transforms into an immutable, free-threaded object:
// System.Windows.Freezable
internal bool Freeze(bool isChecking)
{
    if (isChecking)
    {
        this.ReadPreamble();
        return this.FreezeCore(true);
    }
    if (!this.IsFrozenInternal)
    {
        this.WritePreamble();
        this.FreezeCore(false);
        PropertyMetadata.RemoveAllCachedDefaultValues(this);
        DependencyObject.DependentListMapField.ClearValue(this);
        base.Freezable_Frozen = true;
        base.DetachFromDispatcher(); // lookee here!
        this.FireChanged();
        this.ClearContextAndHandlers();
        this.WritePostscript();
    }
    return true;
}


We will look more into Freezeable objects in later posts, but this usage of DetachFromDispatcher() is entirely expected. This also explains why you can't unfreeze a Freezable object.

[The Polish Ambassador: Lions in the Street -- YouTube]

References

  • Pawan Mishra's blog has a great overview of the Dispatcher class.

WPF: Dispatcher - Application Startup

In my last post, I mentioned that "the Dispatcher" is created automagically at startup. Time to cut through the magic and see what's really happening.


I started up VS.NET 2010, created a new WPF Application called "SimpleApplication", and built and ran the initial pieces dropped in by the project template. In the "obj\x86\Debug" path under the main project folder, I found the automatically generated "App.g.cs" source file, created as a product of my App's build action being set to ApplicationDefinition:
    /// <summary>
    /// App
    /// </summary>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks""4.0.0.0")]
    public partial class App : System.Windows.Application {
       
        /// <summary>
        /// InitializeComponent
        /// </summary>
        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public void InitializeComponent() {
           
            #line 4 "..\..\..\App.xaml"
            this.StartupUri = new System.Uri("MainWindow.xaml", System.UriKind.Relative);
           
            #line default
            #line hidden
        }
       
        /// <summary>
        /// Application Entry Point.
        /// </summary>
        [System.STAThreadAttribute()]
        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public static void Main() {
            SimpleApplication.App app = new SimpleApplication.App();
            app.InitializeComponent();
            app.Run();
        }
    }
This file doesn't make any explicit references to the Dispatcher class, but we can at least see our Main() method now, so something that it's doing must be bringing about that initial Dispatcher instantiation. Looking through all of the partial source files for App.cs, we know that no explicit ctor has been declared, so the construction of our new App instance seems to have no effect beyond the creation of the new object. We can clearly see what InitializeComponent() is doing, so app.Run() must be behind all of the Dispatcher initialization, right?

Using my new best friend ILSpy, I walked down through the Application.Run call chain until I found the first place where the Dispatcher was accessed, hopping through Run(Window) and RunInternal() before landing at RunDispatcher():
// System.Windows.Application
[SecurityCritical]
private object RunDispatcher(object ignore)
{
    if (this._ownDispatcherStarted)
    {
        throw new InvalidOperationException(SR.Get("ApplicationAlreadyRunning"));
    }
    this._ownDispatcherStarted = true;
    Dispatcher.Run();
    return null;
}

The call to Dispatcher.Run() is really two statements in one: it gets the Application.Dispatcher property and then tells that dispatcher to start its loop. The Dispatcher property is defined on Application's base class, DispatcherObject, and is defined like this:
// System.Windows.Threading.DispatcherObject
[EditorBrowsable(EditorBrowsableState.Advanced)]
public Dispatcher Dispatcher
{
    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    get
    {
        return this._dispatcher;
    }
}


Um, okay, this must mean that the _dispatcher instance field is initialized somewhere else. The constructor maybe?
// System.Windows.Threading.DispatcherObject
protected DispatcherObject()
{
    this._dispatcher = Dispatcher.CurrentDispatcher;
}



Aha! So it all boils down to Dispatcher.CurrentDispatcher, which makes loads of sense, though I had expected there to be some lazy initialization involved here.
// System.Windows.Threading.Dispatcher
public static Dispatcher CurrentDispatcher
{
    get
    {
        Dispatcher dispatcher = Dispatcher.FromThread(Thread.CurrentThread);
        if (dispatcher == null)
        {
            dispatcher = new Dispatcher();
        }
        return dispatcher;
    }
}


So there you go. Since we haven't created a dispatcher on our current thread yet, Dispatcher.CurrentDispatcher makes one for us.


There are two main takeaways form this analysis:
  • The Dispatcher for an executable is created the moment the Application object is constructed.
  • Creating any instance of a DispatcherObject has the side effect of creating a Dispatcher on the calling thread.
[Afrojack: Bangduck -- YouTube]

Monday, April 25, 2011

WPF: Dispatcher - Common Scenarios

In WPF circles, when someone mentions "the Dispatcher" they usually mean the instance of the Dispatcher class associated with the UI thread. When using the canonical WPF application startup pattern, this Dispatcher is initialized automagically and is often the only instance ever created during the life of the process.

Most of the classes in WPF enforce thread affinity. If you are developing a multi-threaded application, you must make sure that the visual elements of your application are only accessed on the UI thread. Generally, this means finding "the Dispatcher" and pushing whatever work you require onto its queue.

There are many ways to find "the Dispatcher"; your approach will depend on the complexity of your application and the purity of your architecture:
  • Brute force: Provided you aren't playing any games with multiple AppDomains, Application.Current.Dispatcher will give you the reference you need.
  • View access: All WPF visual elements derive from DispatcherObject. If you have access to a visual element, you can inspect its Dispatcher property.
  • Saving for later: During application startup, if you can guarantee that you are running on the UI thread, store a reference to Dispatcher.CurrentDispatcher for later use while your view models are being initialized.
There are two methods on Dispatcher that queue up new work: BeginInvoke() and Invoke(). BeginInvoke() operates asynchronously, has fewer overloads to wade through, and gives you control over operation cancellation and reprioritization. Invoke() operates synchronously, has twice as many overloads due to extra TimeSpan arguments, and effectively freezes any progress on the thread making the call. While there are cases where Invoke() may be more appropriate, BeginInvoke() supersets its functionality and is more often the superior choice.

[Deadmau5: A City in Florida -- YouTube]

References