Monday, 19 August 2013

Dispatching an action to the UI Thead



When working with multi-threaded applications you often need to poke information back to the main (GUI) thread. 

It could be to update the status bar with information during an asynchronous task or notify the user in a more direct way. 

There are many ways of doing this, but I keep it as simple as possible by Invoking a Dispatcher

Invoking the Dispatcher gets the threading dispatcher of the object you are about to call an action on and subsequently calls it on that thread. 
In order words, it finds the appropriate thread and calls the method on it. 

The Set-up


In this example I have a login box that I want the user to populate with a valid username and password. Once the user clicks 'OK' my application will create a background thread to validate the login. If this takes too long, the user may believe the login has failed or crashed, so we present a Busy indicator with a status update. 

I want to update the busy indicator with the progress of the authentication, but as the authentication class is executed in a separate thread, I must use my Dispatcher. 

First, I must make my Window class accessible:



public partial class Userlogin
{
   public static Userlogin LoginHandle;
       public Userlogin()
       {
        InitializeComponent();
        LoginHandle = this; 
       }
}

This allows for my Window to be called from elsewhere in the application. 

I also have a control in my XAML called Busy

<telerik:RadBusyIndicator Name="Busy" IsBusy="False" HorizontalAlignment="Left" Height="124" Margin="10,56,0,0" VerticalAlignment="Top" Width="334"/>


From anywhere in my application I can now call 'Busy', or any other UI element. 

Window.Userlogin.LoginHandle.Busy.IsBusy = true;


However this does not allow me to do this from another thread, this is where the Dispatcher comes in. 


Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
new Action(() =>
Window.Userlogin.LoginHandle.Busy.BusyContent = "Validating Credentials"));


BeginInvoke calls the delegate on the thread it the dispatcher is associated with. 

Very handy.

No comments:

Post a Comment