Nov 29, 2012 at 3:36 AM
Edited Nov 29, 2012 at 4:06 AM
|
First let me say thank you for creating this project. We've been using MVVM Light for quite some time now and absolutely love it. It's become a core piece of our infrastructure and we continue to use it regularly on all of our projects we create.
That being said, early on we noticed that managing when an application is busy is quite difficult within Silverlight when you have multiple threads pulling data simultaneously. After thinking about this problem for quite some time, I came up with a class
which uses your framework to assist with managing this problem area. I've re-written this class so many times now as I transition to other projects, I have a feeling many other people might find great use for it. So, I am posting it here for your consideration
to include it in your project.
Basically, this class' role is to handle busy state changes within a multi-threaded application as pieces are started and stopped. For example:
Say you have a view model which has to retrieve 3 separate pieces of data in a Silverlight based application using RIA services. In order to decrease load time, you perform the 3 load operations of the data concurrently. If you have some sort of
busy indicator on your page while the data is being retrieved, you need to know when to start and when to stop that indicator. With multiple threads retrieving the data concurrently, having a class that acts as a controller for when each thread starts and
stops is highly useful. Without it, your application may transition between states when one thread finishes before the 2nd thread finishes being started usually causing a flash on the screen. This area is exactly what this class is designed to help manage
by providing a thread-safe mechanism for managing this.
XAML:
<Page.Resources>
<helpers:BusyController x:Key="BusyController"/>
</Page.Resources.
<BusyIndicator IsBusy="{Binding Default.IsBusy, Mode=OneWay, Source={StaticResource BusyController}"/>
In the above example, you have a BusyController instance defined in the page resources, and you can either use the default instance for controlling application-wide busy state, or bind to the IsBusy property on an instance of the BusyController if you
are wanting to control the busy state on a specific control. This example uses a Silverlight Toolkit BusyIndicator control to display a visual indicator that the application is busy doing something.
Usage:
public void LoadData()
{
BusyController.Default.SendMessage(true);
EntityQuery<MyEntity> query = this.DomainContext.GetMyEntityQuery();
this.DomainContext.Load(query, this.LoadDataCompleted, null);
}
private void LoadDataCompleted(LoadOperation<MyEntity> op)
{
BusyController.Default.SendMessage(false);
}
Basically, before each thread begins whatever asynchronous work must be performed, a quick call to the busy controller indicating that the busy state is being changed. And once the operation completes, another call to indicate that the work has finished.
Also, if your application needs to know when the busy state of a controller changes, using the normal registration mechanism for the messenger instance can be used to receive notifications.
Messenger.Default.Register<BusyMessage>(this, (message) =>
{
// Do something useful.
});
The Code:
Rather than posting all of the code here for the class and related message, I'm going to upload it to pastebin. Here is the link:
http://pastebin.com/qqZ14SDm
I hope this post helps someone else, and I hope I see it included with MVVM Light at some point in the future!
- Jeff
Edit: I wanted to add, this class has been used in Windows Phone 7 and 8, WPF, and both Silverlight 4 and 5 applications.
|