Pranay Rana: Dispatcher in Silverlight

Friday, December 21, 2012

Dispatcher in Silverlight


In this I am going to discuss about Dispatcher that makes Silverlight application responsive. I am going to show how Dispatcher allows to update UI of the application on the response from WCF service which is called anonymously and while continue to execute the other task.

Read More : DependencyObject.Dispatcher Property

What is the Example Application about ?
This is application which is fill up the Listbox on UI with the help of Dispather and WCF service which get called Asychronously so the actually thread do the task and doesnt get block.
Secondly On button click on UI its select the product in list which is get fetch using Dispatcher and WCF service.
So application is demonstration of how to use Dispatcher in Silverlight application which make use application more responsive and update UI without blocking other thread.

UI of the silverlight page

in the page "List of Item" item page Listbox get filled with the help of Dispatcher and by calling WCF service asynchronous.

Secondly on Button click  items get selected in listbox which are get fetched by making asynchronous WCF service call and UI get updated by Dispatcher.

Now in following article going to show detail execution of the code behind this Silverlight page and how the Dispatcher  and asynchronous WCF service combination works

Structure of the application
Above is structure of the application its consist of three project
1) DataService - project contains WCF service(s).
2) BusinessApplication1 - Silverlight application i.e. application pages developed using Silverlight.
3) BusinessApplication1.Web - It host Silverlight application.

DataService Project
WCF service
WCF file is part of "DataServicwe" project in application structure. Service file of this application contains following two methods
GetList -  this method get called to return the list of all product , once call is done on UI you can see the list of product get populated.
public List<string> GetList()
{
    List<string> lst = new List<string>
                {"Product1","Product2","Product3","Product4","Product5"};
    return lst;
}
GetSelectedList - this method get list of selected products, which is get highlighted once use press button on UI.
public List GetSelectedList()
{
    List<string> lst = new List<string>
                          {"Product1","Product3","Product5"};
    return lst;
}
Note : Right now for the demo this methods directly return list of string which is hard-coded but in actual scenario this get replace by database call i.e. call to database to get the list of product and call to database to get list of product belonging to user.

BusinessApplication1 (Silverlight Application)
WCF proxy
Proxy is class file which calls WCF service and return response to UI i.e. its bridge between Silvelright UI and WCF service.
Following variable is object of WCF client service class which is generated by visual studio from WCF service which is used in Silvelright application.
Service1Client svr;
GetData Method is called from the xaml.cs page to fill the available product list which is on UI of application.
public void GetData(Action<ObservableCollection<string>,Exception> ac)
{
    svr = new Service1Client();
    svr.GetListAsync(ac);
    svr.GetListCompleted += 
       new EventHandler<GetListCompletedEventArgs>(svr_GetListCompleted);
}
in above method first line of method create instace of WCF client class.
Second line of code call to "GetListAsync" method which is generated by Visual studio and part of WCF Client class , this method is generated from "GetList" of WCF service which we discussed earlier. "ac" is passed as argument to which is method that is used for callback i.e. its XAML.CS method which do the changes in UI.
Third line of code set the event handler which is handle the event of completion of execution on WCF service.

svr_GetListCompleted Following method get called when WCF service complete execution and return response of async call made to service.
void svr_GetListCompleted(object sender, GetListCompletedEventArgs e)
{
    try
    {
     ObservableCollection<string> str = e.Result as ObservableCollection<string>;

     Deployment.Current.Dispatcher.BeginInvoke(
          (Action)(() =>
          {
            (e.UserState as Action<ObservableCollection<string>, Exception>)(str, null);
          }));


    }
    catch (Exception ex)
    {
        Deployment.Current.Dispatcher.BeginInvoke(
           (Action)(() =>
           {
             (e.UserState as Action<ObservableCollection<string>, Exception>)(null, ex);
           }));
    }
    finally
    {
       svr.GetListCompleted -= svr_GetListCompleted;
       svr.CloseAsync();
       svr = null;

     }
}
in the above method , In try block first line get the result of execution i.e. list of product which is return from WCF service.
Now in second line of code in try block Dispatcher calls method of UI whose reference is passed as object by "GetListAsync".
In Catch block if there is any exception occurs during execution than it get sent to UI method to display user.
In Finally block it remove complete handler and closeAsync call and set WCF client class object to null.
Note : You find similar method for button click and select product in product list.

Page CS file
      public MainPage()
        {
            InitializeComponent();
            LoadList();
        }
 first line in the method Initialize the page component and second line of code make call to fill the product list.
        private void LoadList()
        {
            WCFProxy proxy = new WCFProxy();
            proxy.GetData(new Action<ObservableCollection<string>, Exception>(DispalyList));

        }
This method creates the object of Proxy class which is discuss earlier and call the "GetData" method of it, as pass the reference of function called "DisplayList".
public void DispalyList(ObservableCollection<string> data, Exception ex)
        {
            if (ex == null)
                listBox1.ItemsSource = data;
        }
code in this method fill the Listbox with the items once call to WCF service completed.

Below code works same as filling product list code, But this code actually select items in productlist which actually fetch by calling WCF service. This get called on button click of Button of UI.
private void button1_Click(object sender, RoutedEventArgs e)
        {
            WCFProxy proxy = new WCFProxy();
            proxy.GetDataSelected(new Action<ObservableCollection<string>, Exception>(SelecteItems));
        }
public void SelecteItems(ObservableCollection<string> data, Exception ex)
        {
            if (ex == null)
            {
                foreach (string s in data)
                    listBox1.SelectedItems.Add(s);
            }
        } 


Main xaml  
Following is XAML code that is for the UI of application
<UserControl 
  x:Class="BusinessApplication1.MainPage"
  xmlns="
    http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="
 http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:navigation="clr-namespace:System.Windows.Controls;assembly
=System.Windows.Controls.Navigation" 
 
 xmlns:uriMapper="clr-namespace:System.Windows.Navigation;assembly
=System.Windows.Controls.Navigation"
 
 xmlns:dataControls="clr-namespace:System.Windows.Controls;assembly=
System.Windows.Controls.Data.DataForm.Toolkit" 
  
  xmlns:d="
  http://schemas.microsoft.com/expression/blend/2008" 
  xmlns:mc="
  http://schemas.openxmlformats.org/markup-compatibility/2006" 
  mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">

  <Grid x:Name="LayoutRoot" >
        <ListBox Height="149" HorizontalAlignment="Left" Margin="152,12,0,0" Name="listBox1"
 VerticalAlignment="Top" Width="182" />
        <TextBlock Height="23" 
HorizontalAlignment="Left" Margin="39,30,0,0" 
Name="textBlock1" Text="List of Item" VerticalAlignment="Top" />
        
<Button Content="Select Item beloging to user" Height="23" 
HorizontalAlignment="Left" Margin="152,186,0,0" Name="button1"
 VerticalAlignment="Top" Width="182" Click="button1_Click" />
    </Grid>
</UserControl> 

Conclusion
So this helps to build more responsive Silverlight application using Dispatcher.

Leave comment if you have any query or if you like it.
 

No comments:

Post a Comment