Introduction

Probably the most often discussed topic around WPF and Silverlight in the last year or two has been the MVVM (Model View View Model) pattern. MVVM has surfaced as a candidate replacement for similar architectural patterns such as the MVC and MVP patterns, because it leverages specific features of WPF and Silverlight, most notably the data binding infrastructure, to deepen the separation
of the view layer from the rest of an application's layers. This has several benefits, including allowing interactive designers to focus exclusively on the user interface (UI), concurrent development of application layers, and easier testability.

The mechanisms that make MVVM so effective can also be applied to a secondary pattern, one that I have called the Model Thread View Thread pattern (MTVT). It is an approach that may be seen as extending the principles behind MVVM. The MTVT pattern is an architectural pattern used for explicit demarcation of the view and view model via disparate threads of execution. In summary, its main characteristics are that it is comprised of two distinct threads of execution, (one for the view and one for the other application layers), and that cross thread communication occurs transparently over familiar WPF and Silverlight features; such as events (INotifyPropertyChanged, INotifyCollectionChanged etc.) and commands.

In the proof of concept download, I have provided:

A weak referencing event management system that maintains thread affinity with subscribers.

A command class that invokes handlers on an application's model thread.

A synchronized ObservableCollection that allows its collection changed event to be raised on the thread where subscription took place.

And a ViewModelBase class that raises property changes on the subscribers thread.

MTVT is specifically focused on providing for a non-presentation layer centric approach. In MTVT, the execution of model logic is separated from UI controls using an asynchronous threading model.

MTVT displaces the traditional UI centric approach in which the UI thread is the primary thread, and where all activity occurs there by default.

Why a new approach?

MTVT is designed to make use of specific capabilities of WPF and Silverlight to better separate the view or presentation layer at run-time, which in turn provides greater assurance of UI responsiveness and, in the case of Silverlight, facilitates such things as synchronous WCF communication.

.NET GUI applications are traditionally UI thread centric. For example, a developer may provide an event handler for an event, and if the handler is deemed to be a long running activity, then the developer will write code to spin off the work to a worker thread. It is, however, common that the developer will neglect to write the asynchronous code, because the execution time of the handler is underestimated, or it is seen as too laborious to write the code at the time. The ramifications of not doing so, usually don't present themselves until later.

If, on the other hand, the developer takes the approach of invoking all state changes on the UI thread, then not only can we end up with lots of ugly boiler plate code, but we can end up degrading an application's performance if we're not careful.

MTVT, in part, addresses this haphazard approach to delegation. It reduces the need for repetitive coding activities around controlling concurrency, and it alleviates the need to explicitly invoke changes in the UI from the model. Also, explicit designation of a single model thread may help to reduce concurrency issues, which are otherwise inevitable when working with multiple child threads.

Another benefit is that model logic becomes more scalable, as the introduction of new functionality won't slow the UI.

These days we see lots of tools emerging that assist in transparently parallelizing work, (such as PLINQ and TPL). Infrastructure for parallelization will become evermore prevalent, and such technologies focus on abstracting the mechanism for retrieving data, using e.g., LINQ, and focusing on the what not the how. This proof of concept attempts to do the same, in that the mechanisms for raising events, performing commands, and updating collections remain the same.

Background

Some time ago, back in 2008, I published an article in which I describe how to perform blocking WCF service calls (synchronous at the user code level) in Silverlight, thereby removing the asynchronous requirement; which can lead to spaghetti code. It describes a reactor implementation to provide a synchronous interface for the Silverlight asynchronous API. Since then I’ve been surprised by the frequent emails and messages I have received by users that don’t really understand the approach necessary to make it all work fluidly. Many contend that even though it is possible, as I demonstrate how to do it, they have a hard time reconciling the notion that the UI thread should not necessarily be the 'driving' thread. And, I can kind of see why.

MVVM has shown that in most cases, adequate view separation is attainable. However, because both WPF and Silverlight rely on thread affinity with the UI thread, issues around threading occur, and can hinder the application of the pattern. This has lead me to devise MTVT. This pattern lends itself quite naturally to both Silverlight and WPF because of the binding, commanding, and event infrastructure. And as we shall see, I demonstrate how the features can be put to work transparently to support the pattern. There's nothing new to do, (in fact there is less to do), and we don't need to radically change the way we work.

Sample Application

The sample is a rudimentary Silverlight application, which demonstrates the commanding, events, and collection that makes the dual thread approach possible.
It consists of a single page, with a single interactive component: a button.

Figure: Demonstration application.

The "Fire view model command" button has an attached property, which is the Prism Click.Command property.

When the button is clicked, an execution handler located in the MainPageViewModel is invoked on the model thread, as shown in the following excerpt:

void OnTestCommandExecute(object obj)
{
/* Setting of properties will cause the property change handlers to be invoked
* on the thread in which they were subscribed (either the UI or model thread).
* This means we do not need to invoke the change on the UI thread
* as would otherwise be the case. */
Message = "Processing command in view model \n (sleeping to show UI doesn't lock)";
/* Sleep to simulate some long running activity. */
Thread.Sleep(2000);
string newItem = "Test " + ++clickCount;
exampleCollection.Add(newItem);
TestString = newItem;
Message = string.Empty;
}

The Message property of the view model is modified. This property change occurs on the view model thread,
yet the UI is informed of the change via the UISynchronizationContext, which invokes the change handler on the UI thread,
as not to raise an invalid cross thread exception.

Figure: View model is put to sleep, yet the view remains responsive.

Once the model thread is finished sleeping, we add an item to our custom observable collection, which safely invokes its CollectionChanged
event handlers on the UI thread; the thread where the Silverlight data binding infrastructure subscribed to the event.

Figure: Item safely added to the collection.

This demonstrates that we are indeed able to separate the UI thread from the model thread.

There are some subtleties to the implementation. For example, you may be wondering how we are able to handle the CanExecute event handler,
which requires the method to return a result; thereby requiring the UI thread to be blocked. Well, in Silverlight, blocking the UI thread is not an option
because the event loop is serviced by the UI thread. But, we can still achieve the 'enabled/disabled' functionality by using a callback.
This can be seen in the following excerpt from the ModelCommand class, which makes use of Prism's WeakEventHandlerManager.

Here we see that the CanExecute method does not block the caller when invoking the CanExecute event handler on the model thread.
But, what it does do is invokes the handler without blocking, and signals when a result has been obtained by calling the OnCanExecuteChanged method.
This then triggers the CanExecute method to be called a second time. And for the second call the value of canExecuteResultReceived
is used to signal that this time around we have a value, and thus the canExecuteResult is supplied, and the flag reset.

Figure: The ModelCommand makes use of the ModelSynchronizationContext in order to invoke the Execute and CanExecute
event handlers on the model thread.

When a command is executed, as when the button is clicked in the sample application, we see that the event handler is invoked using the ModelSynchronizationContext.
This occurs in a non blocking call, and thus prevents the UI from locking up.

Synchronization Infrastructure

So, we've looked at the sample application. Now let's explore the infrastructure in a bit more detail.
We shall start with the synchronization infrastructure, and look at how it is used to maintain two separate threads of execution, and in particular the
ISynchronizationContext interface, which defines the standard functionality of all synchronization contexts.

ISynchronizationContext Interface

This interface specifies that an Action or SendOrPostCallback may be queued for invocation,
in either a blocking or non-blocking manner.

Figure: ISynchronizationContext class diagram.

There are two implementations of this interface. They are the ModelSynchronizationContext, and the UISynchronizationContext.
Both are tasked with invoking delegates on either the model thread, or UI thread respectively.

ModelSynchronizationContext Class

The ModelSynchronizationClass uses a dedicated thread to invoke a queue of actions or CallbackReferences.
This presents a familiar producer and consumer problem; easily solved with an AutoResetEvent,
which is used to signal when an item has been added to the queue. Thus, we do not need to resort to using a polling mechanism.
The following excerpt is taken from the ModelSynchronizationContext class:

Notice that in either of the InvokeAndBlockUntilCompletion method overloads, to invoke an action, and then block until the action is complete,
we use another AutoResetEvent named itemResetEvent. Whenever the queue is being consumed by our model thread, as each action is completed,
the invokeComplete event is raised, which allows the anonymous handlers (in the InvokeAndBlockUntilCompletion methods),
to test whether the action invoked is the one that is being waited on. If so, this indicates that the action has been invoked, and that the method is free to return.

UISynchronizationContext Class

The other ISynchronizationContext implementation is the UISynchronizationContext.
It makes use of a Dispatcher and a DispatcherSynchronizationContext to do the heavy lifting for us.
In order to perform blocking calls on the UI thread we use a DispatcherSynchronizationContext.
I often see people wondering how to perform blocking calls with the Dispatcher, and here's how it's done: take a Dispatcher
and instantiate a DispatcherSynchronizationContext, then call context.Post(callback, state);

///<spanclass="code-SummaryComment"><summary></span>

Events with Thread Affinity

We have seen how there are two contexts (UISynchronizationContext and ModelSynchronizationContext)
that are used to invoke delegates on the UI and model threads. Let us now turn our attention to the infrastructure which is used to give us events with thread affinity.

DelegateManager Class

In order to invoke a delegate on the same thread that the event was subscribed to, we make use of a DelegateManager.
The DelegateManager class allows us to invoke a list of delegates, where each delegate can be associated with a particular thread.
The DelegateManager also makes use of WeakReferences, which helps to ensure that memory leaks do not occur.
The DelegateManager class is provided here in its entirety:

SynchronizationContextProvider Class

So how do we invoke a delegate on a particular thread? Well, this can't be done arbitrarily.
For that we make use of an extensibility point which I use throughout the proof of concept. It is an IProvider<ISynchronizationContext>
whose default implementation is the SynchronizationContextProvider.
It determines the ISynchronizationContext that is used to associate with a delegate. Notice above, how it is passed to the DelegateManager's constructor.

///<spanclass="code-SummaryComment"><summary></span>

PropertyChangeNotifier Class

The PropertyChangeNotifier makes use of two DelegateManagers. One for the INotifyPropertyChanged event,
and the other for the INotifyPropertyChanging event. This class uses a WeakReference to associate itself with a host class,
in order to take over the responsibilities of property change notification. It also adds some niceties like cancellable changes.
My favourite method from this class is the Assign method. I use it everywhere for property changes, because it

takes care of notifying that the property is about to be changed,

performs the changes (unless it was cancelled),

and then notifies that the change has been performed.

Several examples of its use can be found in the MainPageViewModel class. The following excerpt shows one such example:

The Assign method takes the name of the property, in this case it is a generated name
from the T4 Metadata Generation template,
a reference to the field that may be changed, and the new value.

Returning to the actual implementation of the PropertyChangeNotifier, here it is provided in full:

///<spanclass="code-SummaryComment"><summary></span>

As you will notice, there is also the facility to use lambda expressions for property names, which I wouldn't recommend for poor performance reasons.

So we see that the PropertyChangeNotifier makes use of DelegateManagers to aggregate delegates,
and invoke them when the PropertyChanged or PropertyChanging events are raised.
In order to avoid duplication, I sometimes make use of the NotifyPropertyChangeBase class.

NotifyPropertyChangeBase Class

The NotifyPropertyChangeBase class encapsulates a PropertyChangeNotifier instance, that goes some way to enabling serialization
of the PropertyChangeNotifier, and lazy loading. It also provides for a little terser code, in that field qualification can be omitted.

///<spanclass="code-SummaryComment"><summary></span>

This class serves as the base class for our ViewModelBase class.

ViewModelBase Class

This class is an abstract class that is the base class for all, well, view models. In the proof of concept it has virtually no implementation,
and serves merely as a placeholder for now.

By specifying that our PropertyChangeNotifier maintains thread affinity, it means that event handlers will be executed on the thread
of subscription (either the UI thread or the model thread).

A Collection with Event Thread Affinity

ObservableCollections are frequently used in WPF and Silverlight applications to enable automatic UI updates when items are added to,
or removed from, a collection. Earlier in this article, we looked at the sample application's use of a custom collection in the MainPageViewModel.
This collection was a SynchronizedObservableCollection, which happens to make use of our DelegateManager class in order to associate
the thread on which an event is subscribed, and the handler. This means that when an item is added or removed from the collection,
each NotifyCollectionChangedEventHandler subscriber is notified on the correct thread.
This is important, because UI elements that are data bound to the collection will raise an exception if the handler is not invoked on the UI thread.
If we did not have this mechanism then we would need to manually invoke any updates to the collection on the UI thread.

SynchronizedObservableCollection Class

The SynchronizedObservableCollection looks much like the ObservableCollection implementation in the FCL,
but with some notable differences. It makes use of the DelegateManager, which allows for the INotifyCollectionChanged
event handlers to be invoked on the correct threads. In order to help prevent race conditions,
changes to the collection are invoked on the UI thread using the UISynchronizationContext.

///<spanclass="code-SummaryComment"><summary></span>

Infrastructure Unit Tests

Curiously, the infrastructure that gives us the ability to unit test Silverlight applications does not come with the Silverlight Tools (SDK),
but with the Silverlight Toolkit.

I created some tests during development of the proof of concept. This proved to be very useful during its development,
as it allowed me to debug and identify threads, without relying on the UI.

Figure: Silverlight Unit Testing

The unit testing infrastructure within Visual Studio is not Silverlight Unit Test aware. This means that executing a unit test requires setting
the default page of your application, to the generated unit test page. In the case of the sample application, this is the Tests.aspx page.

Notice that the test itself derives from Microsoft.Silverlight.Testing.SilverlightTest,
which differs from run-of-the-mill Desktop CLR unit tests that use the Microsoft unit testing tools.
Deriving from SilverlightTest affords the ability to perform asynchronous tests, but that is outside of the scope of this article.

Conclusion

In this article we have seen how the Model Thread View Thread pattern uses the same facilities as the MVVM pattern, to better separate the execution of view control specific logic from the rest of the application. This provides us with greater assurance of UI responsiveness, and in the case of Silverlight, facilitates such things as synchronous WCF communication. It also reduces the need for UI thread invocation, and helps to increase model scalability; allowing for event handler logic to grow without degrading UI responsiveness.

This article serves as a definition of the pattern for peer review, and also as proof of concept for the infrastructure required to support the pattern.

I hope you find this project useful. If so, then I'd appreciate it if you would rate it and/or leave feedback below. This will help me to make my next article better.

History

April 2010

Published.

License

This article, along with any associated source code and files, is licensed under The BSD License

Share

About the Author

Daniel Vaughan is a Microsoft MVP and co-founder of Outcoder, a Swiss software and consulting company dedicated to creating best-of-breed user experiences and leading-edge back-end solutions, using the Microsoft stack of technologies--in particular WPF, UWP, and the Xamarin tools.

Daniel is the author of Windows Phone 8 Unleashed and Windows Phone 7.5 Unleashed, both published by SAMS.

Daniel is the developer behind several acclaimed mobile apps including Surfy Browser for Android and Windows Phone. Daniel is the creator of a number of popular open-source projects, most notably the Calcium MVVM Toolkit.

Would you like Daniel to bring value to your organisation? Please contact

After integration by adding DLL's and CS files to my current Silverlight Project I got an error "Microsoft.Practices.Composite.Presentation.Commands.WeakEventHandlerManager is inaccessible due to its protection level" on ModelCommand.cs file. Please help"

This is a very interesting piece of work that caught my attention, but I would like to use it in a WPF environment. Reviewing the source code it seems as though this would be possible with the addition of some WPF specific base classes - but I thought I would ask here before digging into the task - or perhaps I have missed something?

I am sure that the UI thread remains constant, not sure at this point about the worker threads. The SynchronizationContextProvider gives the current UI thread at all times. Is that the same with the worker thread?

I'd like to say that this article presents some nice ideas, however, in many respects it seems like you've used a crow bar to open a can of beans.

Firstly, why write your own SynchronizationContext when you already have the DispatcherSynchronizationContext provided for you in Silverlight.

In many respects your implementation is based on the Async Event Pattern, which is already well documented. For example, you should use AsyncOperationManager to get an AsyncOperation which can be used to synchronize callbacks. This will automatically use the DispatcherSyncrhonizationContext if the calls are initiated from the UI thread (Which in your case they are).

Also, your observable collection is shared between the UI thread and the Model thread, and should therefore be "properly" synchronized, for example, gets, adds, inserts, etc. should be wrapped with a lock. (You do not override the item get). If you do not, then you could be adding to your collection whilst the user is scrolling through a list of results (For example in a DataGrid), as the DataGrid is Virtualized it could be accessing the Item whilst you are growing the collection (Splat).

Firstly, why write your own SynchronizationContext when you already have the DispatcherSynchronizationContext provided for you in Silverlight.

This is done for a number of reasons:SynchronizationContext.Current can be null on child threads. Thus I perform some extra steps to create a DispatcherSynchronizationContext using the Deployment.Current.Dispatcher.I wanted to add overloads for posting and sending Actions.It enables a common interface, ISynchronizationContext, for both UI and model threads, to support both WPF and Silverlight.I use the provider pattern with the strongly typed ISynchronizationContext.

suedama1756 wrote:

For example, you should use AsyncOperationManager to get an AsyncOperation which can be used to synchronize callbacks. This will automatically use the DispatcherSyncrhonizationContext if the calls are initiated from the UI thread (Which in your case they are).

And if not initiated from the UI thread, they will be either invoked on the UI thread using the Send method, or invoked on an AppPool thread using Post. This is not at all what we want as it does not give model thread affinity, and may force model logic being performed on the UI thread.

suedama1756 wrote:

Also, your observable collection is shared between the UI thread and the Model thread, and should therefore be "properly" synchronized, for example, gets, adds, inserts, etc. should be wrapped with a lock. (You do not override the item get). If you do not, then you could be adding to your collection whilst the user is scrolling through a list of results (For example in a DataGrid), as the DataGrid is Virtualized it could be accessing the Item whilst you are growing the collection (Splat).

It won't 'splat' because ClearItems, CopyFrom, InsertItem etc are performed on the UI thread. In my first implementation I went all out to provide a thread safe implementation. It’s not really achievable. There are approaches out there that use dual collections, but I still see these as containing opportunities for race conditions. And so I chose to go with UI thread affinity. It solves a lot of challenges, and is much simpler. I realize the indexer is not overloaded, and that can be done in the future. There will be some things that will simply not be thread safe without the use of a lock, and I realize there is more to be done in the collection, but in this POC I think it suffices.

Ok, I admit I skimmed the SynchronizedObservableCollection implementation. I'd missed the fact that the collection was performing the adds, sets, etc. on the UI Thread and blocking the calling thread until this was completed. There are some elements of this design that I like (although I'm not sure whether its just because its clever, rather than because I can see a practical use), time will tell on that one

There are a couple of things that trouble me still, firstly the name, if the collection is implicitly using the UISynchronizationContext then perhaps this should be made clear, perhaps UISynchronizedObservableCollection (althoug a bit long )

Also, I'd be interested in your thoughts on whether you see the collection as being part of the view or the model? From the implementation is seems View, as it has UI thread affinity.

As every add is synced back to the UIThread whilst blocking the Model thread, I'm not sure where you expect to see performance, or responsiveness gains. You'd have to be adding a lot of items (which has a bad smell about it), or be drip feeding from the model where each item is produced from a long running op for this to offer any real advantage.

On the SynchronizationContext front, did you consider adding the extra methods you required using extension methods with closures?

Really a good article, well explained, informative and full of stuff I can use for my current project! (You've got my 5)

Still, I've got a couple of comments!

1. About SynchronizedObservableCollectionI suppose that it does not use a PropertyChangeNotifier to avoid unneeded code (i.e. thread-marshaling code): the collection itself is manipulated on the UI thread to avoid race conditions, so there is no need for specific code for property-changed events. Anyway, I would still cache event arguments like the PropertyChangeNotifier code does, since there is no reason to re-create such objects on every collection change (tipically, collections are changed in bursts, so there is plenty of time for the GC to reclaim such simple objects, still it is an encouraged pattern).

2. About the usage of ReaderWriterLockSlimThe way you are using the synchronization object

I thik it is perhaps a little more than I need at the moment. It solves a lot of problems I have not been faced with… yet, in my limited implementation of SilverLight but I will keep this article handy for the coming months!

I have a questing regarding command execution. I might have misunderstood some detail, but would it not be nice to support some pre command processing delegate that invoked on the UI thread before the command delegate, running on the model thread, is invoked?

Lets assume that a command corresponding to e.g. a button, should disable other UI elements while the command is running and then enable the elements when finished. If this disable code is included within the executeMethod delegate, there is a possibility that the UI responsiveness, the UI thread, allows the user to access the UI elements that should have been disabled by the button click.

By providing some pre command delegate, that will run on the UI thread before the command delegate on the model thread is triggered, the disabling code could do the work safely without concurrency issues.

The enabling code can be included withing the executeMethod delegate so no separate post command delegate is needed.

Well, that will usually suffices in the single threaded environment, where the UI thread handles all activities. But with the article solution, won't it take "a while" before the flag can be set from the model thread and then trigger the UI thread to update the UI?

Maybe that "a while" is small enough to be discarded, but one never knows how fast the model thread is scheduled to run after the UI thread has called Invoke.

I am not sure if article mentions if there is one model thread doing all model activities or if there are several model threads.

In the first case with one model thread, the CanExecute() method will set all commands to canExecute = false while the original command runs. If the UI thread somehow is triggered to check the CanExecute (I don't know if that is handled by the UI thread automatically). But commands that should have there canExecute = true cannot have that set until the original command has finished since the model thread cannot update the canExecuteResultReceived. Thus only one command can be active at one time.

For e.g. an text field, where the IsEnabled flag is bound to some enabled property, the original command will trigger that when the model thread is scheduled to run the command delegate. But that could take "a while" and thus allow the user to start editing a field before it is disabled.

In the later case, where there are multiple model threads, the canExecute is set to false first for all commands and then after a "a while" set to true for those command that wants that. But once again, it is "a while" before that happens.So maybe it would be useful to be able specify some delegate that is run on the UI thread to guarantee that the flag is set before that command is run on the model thread. I guess it is pretty easy to change that if it really is needed.

I am not sure if article mentions if there is one model thread doing all model activities or if there are several model threads.

The proof of concept demonstrates the use of a single dedicated model thread, however I do have plans to augment it for multiple model threads.

You raise a valid point. The ModelCommand implementation returns false when retrieving the CanExecute result from the model. So perhaps it will be adequate for most cases. For more complex scenarios, what I have to say next may be worth considering. I like to think of CanExecute as being like security provisioning (or trimming). I normally take a defensive approach and test whether the command can be executed in the Execute handler, regardless of any previous evaluation. This approach has the residual effect of avoiding race conditions.