Showing posts with label asynch wpf. Show all posts
Showing posts with label asynch wpf. Show all posts

Monday, August 8, 2011

Implicit DataTempates in Silverlight 5 Beta

In this post we are going to discuss a new feature expected to be released in Silverlight 5. This feature is implicit DataTemplates. Those who come from WPF background to Silverlight often find it difficult to design without implicit DataTemplates. Well, this limitation has been worked in Silverlight 5 and it is available in the beta release. Silverlight 5 beta tools can be downloaded from here:

http://www.microsoft.com/download/en/details.aspx?id=23887

Let's create a sample Silverlight application and name it AppSilverlightImplicitDataTemplates.


Make sure that you have Silverlight 5 option selected in the following screen displayed right after the previous one.


You would need a reference of System.Windows.Controls.Data.Input assembly for Labels. If you directly drag and drop the Label Control from Toolbox on the designer surface, the assembly is automatically referenced.


Let's suppose we have the following view model. It has a collection of students. We want the user to select a particular student and allow that to be edited.
namespace AppSilverlightImplicitDataTemplates
{
    using System.Collections.ObjectModel;
    using System.Collections.Generic;

    public class MainViewModel : ViewModelBase
    {
        ObservableCollection<StudentViewModel> _students;
        public  ObservableCollection<StudentViewModel> Students
        {
            get
            {
                if (_students == null)
                {
                    _students = new ObservableCollection<StudentViewModel>();
                    _students.Add(new StudentViewModel() { StudentFirstName = "Muhammad", StudentLastName = "Siddiqi" });
                    _students.Add(new StudentViewModel() { StudentFirstName = "Jayson", StudentLastName = "Abante" });
                    _students.Add(new StudentViewModel() { StudentFirstName = "Meena", StudentLastName = "Gulla" });                                        
                }
                return _students;
            }
        }
    }
}
The view model is inheriting from ViewModelBase class. It is basically for providing general functionality to all view models specially implementation of INotifyPropertyChanged interface. As you might have guessed, like this view model, all others view models in the application would also be inheriting from this.
namespace AppSilverlightImplicitDataTemplates
{
    using System.ComponentModel;

    public class ViewModelBase : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged Implementation

        public event PropertyChangedEventHandler PropertyChanged = delegate { };
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

    }
}
In MainViewModel we have used StudentViewModel collection. It basically has two properties StudentFirstName and StudentLastName. Its definition can be as follows:
namespace AppSilverlightImplicitDataTemplates
{
    using System.ComponentModel;

    public class StudentViewModel : ViewModelBase
    {
        #region Notifiable Properties

        string _studentLastName;
        public string StudentLastName
        {
            get { return _studentLastName; }
            set
            {
                _studentLastName = value;
                OnPropertyChanged("StudentLastName");
            }
        }

        string _studentFirstName;
        public string StudentFirstName
        {
            get { return _studentFirstName; }
            set
            {
                _studentFirstName = value;
                OnPropertyChanged("StudentFirstName");
            }
        }

        #endregion

    }
}
As you can see above, it also inherits from ViewModelBase. The two properties support change notification by calling OnPropertyChanged method. In turn this would raise PropertyChanged event. As we have discussed already that we would be needing to use this view model in two different types of views. One is just for display for selection based control used to display the collection of students. We also need a different view to allow a student to be edited.

For displaying in collection based control:
<UserControl x:Class="AppSilverlightImplicitDataTemplates.StudentDisplayView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" >    
    <TextBlock>
        <Run Text="{Binding StudentLastName}" FontWeight="Bold" />
        <Run Text="," />
        <Run Text="{Binding StudentFirstName}" />
    </TextBlock>
</UserControl>

For editing StudentViewModel:
<UserControl x:Class="AppSilverlightImplicitDataTemplates.StudentEditView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    
        mc:Ignorable="d"
        xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" >
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="93" />
            <ColumnDefinition Width="307" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>           
            <RowDefinition Height="35" />
            <RowDefinition Height="*" />            
        </Grid.RowDefinitions>     
        <sdk:Label Height="23" HorizontalAlignment="Left"
                   Margin="12,12,0,0"  VerticalAlignment="Top"                    
                   Content="First Name" Width="83" Grid.ColumnSpan="2" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="8,8,0,0" 
                 VerticalAlignment="Top" Width="287" Text="{Binding StudentFirstName}" Grid.Column="1" />
        <sdk:Label Content="Last Name" Height="23" HorizontalAlignment="Left" 
                   Margin="12,7,0,0" VerticalAlignment="Top" Width="83" Grid.Row="1" Grid.ColumnSpan="2" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="8,3,0,0" 
                 VerticalAlignment="Top" Width="287" Grid.Row="1" 
                 Text="{Binding StudentLastName}" Grid.Column="1" />
    </Grid>
</UserControl>

Using UserControls in DataTemplate
By default we need the StudentViewModel type of objects to be using the display one. So we can define it as application resource. Just updated App.xaml as follows:
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             x:Class="AppSilverlightImplicitDataTemplates.App"
             xmlns:local="clr-namespace:AppSilverlightImplicitDataTemplates"
             >
    <Application.Resources>
        <DataTemplate DataType="local:StudentViewModel">
            <local:StudentDisplayView />
        </DataTemplate>
    </Application.Resources>
</Application>
Now we define the Main application view. As we have discussed, we need to provide a collection of Students and allow the user to select any one of them and edit that.
<UserControl x:Class="AppSilverlightImplicitDataTemplates.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:AppSilverlightImplicitDataTemplates"
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400"
        xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
    <UserControl.DataContext>
        <local:MainViewModel />
    </UserControl.DataContext>    
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="97*" />
            <ColumnDefinition Width="303*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="43*" />
            <RowDefinition Height="257*" />
        </Grid.RowDefinitions>
        <sdk:Label Height="22" HorizontalAlignment="Left" Margin="11,18,0,0"
                   Name="label1" VerticalAlignment="Top" Width="86"
                   Content="Select Student" DataContext="{Binding Path=Students}" />
        <ComboBox Height="24" HorizontalAlignment="Left" Margin="6,14,0,0"
                  Name="cmbStudents" VerticalAlignment="Top" Width="285"
                  ItemsSource="{Binding Students}" Grid.Column="1" />
        <ContentControl 
            DataContext="{Binding ElementName=cmbStudents, Path=SelectedItem}" 
            Content="{Binding}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" 
            Margin="11,18,0,0"/>
    </Grid>
</UserControl>
Now lets run the application. It appears as follows:


Now select a student from the combo box. The same student is loaded in the ContentControl as follows:


Now we need the ContentControl to be using the editing type of UserControl for StudentViewModel so that it could be edited. Let's override it as follows in the main view:
<UserControl x:Class="AppSilverlightImplicitDataTemplates.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:AppSilverlightImplicitDataTemplates"
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400"
        xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
    <UserControl.DataContext>
        <local:MainViewModel />
    </UserControl.DataContext>    
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="97*" />
            <ColumnDefinition Width="303*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="43*" />
            <RowDefinition Height="257*" />
        </Grid.RowDefinitions>
        <sdk:Label Height="22" HorizontalAlignment="Left" Margin="11,18,0,0"
                   Name="label1" VerticalAlignment="Top" Width="86"
                   Content="Select Student" DataContext="{Binding Path=Students}" />
        <ComboBox Height="24" HorizontalAlignment="Left" Margin="6,14,0,0"
                  Name="cmbStudents" VerticalAlignment="Top" Width="285"
                  ItemsSource="{Binding Students}" Grid.Column="1" />
        <StackPanel Margin="11,18,0,0" Grid.Row="1" 
                    Grid.Column="0" Grid.ColumnSpan="2" >
            <StackPanel.Resources>
                <DataTemplate DataType="local:StudentViewModel" >
                    <local:StudentEditView />
                </DataTemplate>
            </StackPanel.Resources>
            <ContentControl 
            DataContext="{Binding ElementName=cmbStudents, Path=SelectedItem}" 
            Content="{Binding}" 
            />
        </StackPanel>
    </Grid>
</UserControl>
Here we have thrown the ContentControl inside a StackPanel. In the Resources section of the StackPanel, we have overridden the DataTemplate for StudentViewModel. Since local resource have preference over application level resources so this DataTemplate is applied for the StudentViewModel in ContentControl. When we run the application and select a student, the instance is loaded in the ContentControl with correct DataTemplate applied.


Download:

Wednesday, March 2, 2011

Rx - Executing IObservable in Parallel in a WPF application

In this post we are going to take the asynchronous code execution using Reactive extension a bit further. We would see how we can have multiple IObservable (s) are executed in parallel. Rx supports this using Observable.ForkJoin. We can have code executed in parallel which doesn't return any data, return same or different data.

It's not blocking rather still asynchronous:
Let's create a simple view with a single message and a button. We need to execute the IObservable in parallel when button is clicked.
<Window x:Class="WpfApp_Reactive_ForkJoin.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApp_Reactive_ForkJoin"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <TextBlock Height="47" HorizontalAlignment="Left" Margin="70,63,0,0" 
                   Name="textBlock1" Text="{Binding Message}" VerticalAlignment="Top" Width="384" />
        <Button Content="Start Operations" Height="38" HorizontalAlignment="Left" Margin="68,134,0,0"
                Name="btnStartOperations" VerticalAlignment="Top" Width="143" 
                Command="{Binding OperationCommand}"/>
    </Grid>
</Window>
The view is assigning an instance of MainWindowViewModel as the DataContext of the Window. The view expects Message property from the view model to bind it to the Text property of the TextBlock. It also expects an ICommand OperationCommand in the view model. We are implementing INotifyPropertyChanged so we need to provide PropertyChanged event in this view model. It has Message property which is bound to the Text property of the TextBlock in the view.
class MainWindowViewModel : INotifyPropertyChanged
{
    #region Constructor
    public MainWindowViewModel()
    {

    }
    #endregion Constructor

    #region Public Properties

    string _message = "Operation not started yet...";
    public string Message
    {
        get { return _message; }
        set
        {
            _message = value;
            OnPropertyChanged("Message");
        }
    }

    #endregion Properties

    #region INotifyPropertyChanged implementation

    public event PropertyChangedEventHandler PropertyChanged = delegate { };
    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion INotifyPropertyChanged implementation

    #region Operation Command

    RelayCommand _operationCommand;
    public ICommand OperationCommand
    {
        get
        {
            if (_operationCommand == null)
            {
                _operationCommand = new RelayCommand(param => this.StartOperation(),
                    param => this.CanStartOperation);
            }
            return _operationCommand;
        }
    }

    bool CanStartOperation
    {
        get
        {
            return true;
        }
    }

    [DebuggerHidden]
    public void StartOperation()
    {
        Message = "Operation running";

        Observable.ForkJoin(
            Observable.Start(() => { 
                                       Message = "In 1st Observable.Start";
                                       Debug.WriteLine("Executing 1st on Thread: {0}", Thread.CurrentThread.ManagedThreadId);
                                       Thread.Sleep(2000);
                                   }),
            Observable.Start(() => { 
                                       Message = "In 2nd Observable.Start";
                                       Debug.WriteLine("Executing 2nd on Thread: {0}", Thread.CurrentThread.ManagedThreadId);
                                       Thread.Sleep(2000);
                                   }),
            Observable.Start(() => { 
                                       Message = "In 3rd Observable.Start";
                                       Debug.WriteLine("Executing 3rd on Thread: {0}", Thread.CurrentThread.ManagedThreadId);
                                       Thread.Sleep(10000);
                                       throw new System.Exception("exception");
                                   })
            )
            .Subscribe(
                        (result) => { 
                                        Message = result.ToString();
                                        Debug.WriteLine("OnNext: Executing 1st on Thread: {0}", Thread.CurrentThread.ManagedThreadId);
                                        Thread.Sleep(2000); 
                                    },
                        (ex) => 
                                { 
                                    Message = ex.Message;
                                    Debug.WriteLine("OnError: Executing 1st on Thread: {0}", Thread.CurrentThread.ManagedThreadId);
                                    Thread.Sleep(2000); 
                                },
                        () => { 
                                Message = "Completed";
                                Debug.WriteLine("Completed: Executing 1st on Thread: {0}", Thread.CurrentThread.ManagedThreadId);
                                Thread.Sleep(2000);
                              });            
    }

    #endregion Operation Command
}
You can see that we have used an instance of RelayCommand for OperationCommand. Yes, this is the same RelayCommand which is from Josh Smith's MVVM article. Since we want the button always to be enabled so CanStartOperation always returns true. We have used StartOperation as Execute method for OperationCommand.

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

The following marble diagram might be used to represent the behavior of Fork.Join when all asynchronous operations actually return data. All this data is combined to generate a single OnNext with combined data. Since there is no exception so OnCompleted is generated when all data streams are completed.


Can Only Observable.Start be used?
In the above example we have used Observable.Start. We can use any IObservable no matter how it is created. We can even use IObservable (s) resulting from Observable.ToAsync from methods we want to execute asynchronously.
Observable.ForkJoin(
    Observable.Start(() => { 
                               Message = "In 1st Observable.Start";
                               Debug.WriteLine("Executing 1st on Thread: {0}", Thread.CurrentThread.ManagedThreadId);
                               Thread.Sleep(2000);
                           }),
    Observable.Start(() => { 
                               Message = "In 2nd Observable.Start";
                               Debug.WriteLine("Executing 2nd on Thread: {0}", Thread.CurrentThread.ManagedThreadId);
                               Thread.Sleep(2000);
                           }),
    Observable.ToAsync(myMethod)()
    )
    .Subscribe(
                (result) => { 
                                Message = result.ToString();
                                Debug.WriteLine("OnNext: Executing 1st on Thread: {0}", Thread.CurrentThread.ManagedThreadId);
                                Thread.Sleep(2000); 
                            },
                (ex) => 
                        { 
                            Message = ex.Message;
                            Debug.WriteLine("OnError: Executing 1st on Thread: {0}", Thread.CurrentThread.ManagedThreadId);
                            Thread.Sleep(2000); 
                        },
                () => { 
                        Message = "Completed";
                        Debug.WriteLine("Completed: Executing 1st on Thread: {0}", Thread.CurrentThread.ManagedThreadId);
                        Thread.Sleep(2000);
                      });            

Observable.ForkJoin and Exception Handling:
If any of the IObservable results in an exception the no OnNext message is generated from the resulting IObservable but a single OnError is generated. We can show this on a marble diagram as follows:


Operations returning different Data:
For Observable.ForkJoin, we can combine IObservable(s) which return no data or same / different data. Yes, it is possible that we have IObservable resulting in different data. We can use a different Overload of Observable.ForkJoin for this.
public void StartOperation()
{
    Observable.ForkJoin<int, string, string>(
        Observable.Start<int>(() =>
            {
                Thread.Sleep(2000);
                return 1;
            }),
        Observable.ToAsync<string>(myMethod)(),
        (StudentId, StudentName) => { return string.Format("Student- Id: {0}, Name: {1}", StudentId, StudentName); }
    ).Subscribe(
            (result) => { Message = result; },
            (ex) => { Message = ex.Message; });
}

private string myMethod()
{
    Thread.Sleep(5000);
    return "Muhammad";
}
When we run the application and click StartOperation. After some delay(simulated operational delay in parallel streams using Thread.Sleep) the window is updated. We can also use IObservables directly created using Observable.Create() method
public void StartOperation()
{
    Observable.ForkJoin<int, string, string>(
        Observable.Create<int>(
            (o) =>
            {
                Thread.Sleep(2000);
                o.OnNext(1);
                o.OnCompleted();

                return () => { };
            }),
            Observable.CreateWithDisposable<string>(
            (o) =>
            {
                Thread.Sleep(2000);
                o.OnNext("Muhammad");
                o.OnCompleted();

                return Disposable.Empty;
            }),
            (StudentId, StudentName) => { return string.Format("Student- Id: {0}, Name: {1}", StudentId, StudentName); }
    ).Subscribe(
            (result) => { Message = result; },
            (ex) => { Message = ex.Message; });

}
Let's run this. When we click the button the view updates as follows:


Many OnNext messages on Individual IObservable (s)
Observable.ForkJoin combines the last values of each Observable stream, combines them and generates OnNext message on the resulting IObservable.
public void StartOperation()
{
    Observable.ForkJoin<int, string, string>(
        Observable.Create<int>(
            (o) =>
            {
                Thread.Sleep(2000);
                o.OnNext(1);
                o.OnNext(2);
                o.OnCompleted();

                return () => { };
            }),
            Observable.Create<string>(
            (o) =>
            {
                Thread.Sleep(2000);
                o.OnNext("Muhammad");
                o.OnCompleted();

                return () => { };
            }),
            (StudentId, StudentName) => { return string.Format("Student- Id: {0}, Name: {1}", StudentId, StudentName); }
    ).Subscribe(
            (result) => { Message = result; },
            (ex) => { Message = ex.Message; });

}
When we run this, the first IObservable places two OnNext with data 1 and 2 sequentially. The second IObservable results in data "Muhammad". Let's run this:


It is because the third argument from this overload of Observable.ForkJoin has been used as a selector function. It has combined StudentId (int) and StudentName (string) into a string and placed OnNext on the resulting Observable.ForkJoin IObservable. When OnNext is received from the resulting IObservable, it has updated the Message property with the same message. Since this is bound to the view using WPF Binding System, the view is updated with this message.

Cleanup after Parallel Operations:
If we need to do some cleanup after these parallel operations are completed then we can do that in the Finally block executed after IObservable from Observable.ForkJoin finishes. As we know this gets executed no matter if these parallel operations were successful resulting in OnCompleted or there was some exception from any of the operations. In the latter case this gets executed after OnError is executed.

Observable.ForkJoin and Thread Management:
All the IObservable (s) in ForkJoin would be executing on different ThreadPool threads. The resulting IObservable would also be running on a TheredPool thread. Since ThreadPool threads might be recycled, it is possible that the same thread seems to be used for OnNext and OnCompleted as one of the threads used for executing one of the IObservable code. It must be remembered that OnNext, OnCompleted will always be executing on the same thread.
public void StartOperation()
{
    Message = "Operation running";

    Observable.ForkJoin(
        Observable.Start(() =>
        {
            Message = "In 1st Observable.Start";
            Debug.WriteLine("Executing 1st on Thread: {0}, IsThreadPoolThread: {1} ", 
                Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
            Thread.Sleep(2000);
        }),
        Observable.Start(() =>
        {
            Message = "In 2nd Observable.Start";
            Debug.WriteLine("Executing 2nd on Thread: {0}, IsThreadPoolThread: {1}",
                Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
            Thread.Sleep(2000);
        }),                
        Observable.Start(() => 
        { 
            Message = "In 3rd Observable.Start";
            Debug.WriteLine("Executing 3rd on Thread: {0}, IsThreadPoolThread: {1}", 
                Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
            Thread.Sleep(2000);                                           
        }))
        .Subscribe(
                    (result) =>
                    {
                        Message = result.ToString();
                        Debug.WriteLine("OnNext: Executing on Thread: {0}, IsThreadPoolThread: {1}", 
                            Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
                        Thread.Sleep(2000);
                    },
                    (ex) =>
                    {
                        Message = ex.Message;
                        Debug.WriteLine("OnError: Executing on Thread: {0}, IsThreadPoolThread: {1}", 
                            Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
                        Thread.Sleep(2000);
                    },
                    () =>
                    {
                        Message = "Completed";
                        Debug.WriteLine("Completed: Executing on Thread: {0}, IsThreadPoolThread: {1}", 
                            Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
                        Thread.Sleep(2000);
                    });
}

Executing 1st on Thread: 3, IsThreadPoolThread: True
Executing 2nd on Thread: 12, IsThreadPoolThread: True
Executing 3rd on Thread: 11, IsThreadPoolThread: True
OnNext: Executing on Thread: 11, IsThreadPoolThread: True
Completed: Executing on Thread: 11, IsThreadPoolThread: True

Executing 1st on Thread: 11, IsThreadPoolThread: True
Executing 2nd on Thread: 10, IsThreadPoolThread: True
Executing 3rd on Thread: 12, IsThreadPoolThread: True
OnNext: Executing on Thread: 12, IsThreadPoolThread: True
Completed: Executing on Thread: 12, IsThreadPoolThread: True

Executing 1st on Thread: 11, IsThreadPoolThread: True
Executing 2nd on Thread: 10, IsThreadPoolThread: True
Executing 3rd on Thread: 12, IsThreadPoolThread: True
OnNext: Executing on Thread: 3, IsThreadPoolThread: True
Completed: Executing on Thread: 3, IsThreadPoolThread: True


Download Code:

Friday, February 25, 2011

WPF - Performance Improvement for MVVM Applications - Part # 2

This is the second part of our discussion about performance improvement of an MVVM based application. You can find the other part of this discussion here:

- Part - 1: http://shujaatsiddiqi.blogspot.com/2011/01/wpf-performance-improvement-for-mvvm.html

- Part - 3: http://shujaatsiddiqi.blogspot.com/2011/03/wpf-performance-improvement-for-mvvm.html

In this example we would see how we can utilize Lazy Initialization to improve the performance of MVVM based application. Lazy initialization is a newly available features of .net framework 4.0. As I remember this is based on Tomas Petricek's suggestion which has been incorporated in .net framework recently. This is a part of effort to incorporate lazy execution in c# code. You might already know that LINQ queries support lazy evaulation already. They are only evaluated when the first time they are enumerated. If they are never enumerated then never such evaluation takes place. With new Lazy initialization feature, the framework now also supports lazy initialization.

http://msdn.microsoft.com/en-us/vcsharp/bb870976

In this example we would base our discussion on a hierarchical view model. The main view is consisted of some collection based controls. Each of these control also needs to define its template to specify how different items in the collection would be displayed on the screen.

Let's consider a view for a Course with just two students. The data of students should be displayed in tab items in a TabControl. The student information should only have two fields, their first and last names. Student's First name should be displayed as header of its TabItem. If the data is not entered yet then it should display "Default" in the header. The XAML definition of the view is as follows:
<Window x:Class="WpfApp_MVVM_LazyInitialize.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp_MVVM_LazyInitialize"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>        
<TabControl Height="288" HorizontalAlignment="Left" Margin="12,12,0,0" Name="tabControl1" VerticalAlignment="Top" Width="480"
ItemsSource="{Binding StudentViewModels}" >
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding StudentFirstName}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>                
<DataTemplate>
<Grid>
<Label Content="First Name" Height="27" HorizontalAlignment="Left" 
Margin="12,29,0,0" Name="label1" VerticalAlignment="Top" Width="105" />
<TextBox Height="30" HorizontalAlignment="Left" Margin="123,29,0,0" 
Name="textBoxFirstName" VerticalAlignment="Top" Width="345" 
Text="{Binding Path=StudentFirstName}" />
<Label Content="Last Name" Height="27" HorizontalAlignment="Left" Margin="12,65,0,0" 
Name="label2" VerticalAlignment="Top" Width="105" />
<TextBox Height="30" HorizontalAlignment="Left" Margin="123,65,0,0" 
Name="textBoxLastName" VerticalAlignment="Top" Width="345" 
Text ="{Binding StudentLastName}" />
</Grid>                    
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
</Window>

We would be needing two DataTemplates for TabControl. One is for Header i.e. ItemTemplate and the other is for the content of each TabItem i.e. ContentTemplate. The ItemsSource of this TabControl is bound to StudentViewModels collection. Each member of this collection should have atleast two properties StudentFirstName and StudentLastName. The ItemTemplate is just a TextBlock. The Text property of this TextBlock is bound to item's StudentFirstName property. The ContentTemplate has two TextBox(es). One of them is bound to StudentFirstName and the other is StudentLastName properties. We have kept the code behind of the view as default.

The DataContext of the above view is set as a new instance of MainWindowViewModel. It implements INotifyPropertyChanged so it needs to provide definition of PropertyChanged event as part of its contract. As required by the view, it provides a collection StudentViewModels. It is provided as an ObservableCollection. Each member of this generic collection is specified as of the type StudentViewModel.
class MainWindowViewModel : INotifyPropertyChanged
{
ObservableCollection<StudentViewModel> _studentViewModels = 
new ObservableCollection<StudentViewModel>();

public ObservableCollection<StudentViewModel> StudentViewModels
{
get
{
return _studentViewModels;
}
}

public MainWindowViewModel()
{
_studentViewModels.Add(new StudentViewModel());
_studentViewModels.Add(new StudentViewModel());
}

public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

In the constructor of the above view model we have added two members to the collection. As expected they are of type StudentViewModel. They would be displayed as Tab items in the view. The definition of StudentViewModel is as follows:
class StudentViewModel : INotifyPropertyChanged
{
Lazy<Student> _model = new Lazy<Student>();

string _studentFirstName;
public string StudentFirstName
{
get { return _studentFirstName; }
set
{
if (_studentFirstName != value)
{
_studentFirstName = value;
_model.Value.StudentFirstName = value;
OnPropertyChanged("StudentFirstName");
}
}
}

string _studentLastName;
public string StudentLastName
{
get { return _studentLastName; }
set
{
if (_studentLastName != value)
{
_studentLastName = value;
_model.Value.StudentLastName = value;
OnPropertyChanged("StudentLastName");
}
}
}

public StudentViewModel()
{
_studentFirstName = "Default";
}

public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

As expected by the view it has two properties StudentFirstName and StudentLastName. It implements INotifyPropertyChanged to support change notification.

The above view model uses Student as model. When the view model receives updates in these properties through WPF Biniding System, it just passes on those updates to the model. The instances initialized with Lazy initialization feature are accessed using Value property of the Lazy object reference. We have accessed StudentName and StudentLastName properties using the same. Let us assume that it were a model which requires a heavy instantiation. We are just displaying a MessageBox in the constructor. This would show a MessageBox from the constructor. In this way we would realize exactly when the constructor is called. This is how are trying to understand Lazy initialization of Student.
class Student
{
public string StudentFirstName { get; set; }
public string StudentLastName { get; set; }

public Student()
{
MessageBox.Show("Student constructor called");
}
}

Now let us run this. The application is shown as follows:



Enter some data in the First Name field of the first Tab Item. As soon as the focus is changed to the other field, the default Binding of Text property of TextBox triggers the source updates on LostFocus.


When you close the message box you can see the header of the TabItem being updated with the FirstName you entered.



Deciding which Constructor to use for initialization:
We can also decide which constructor of the type we want to use for initialization using the constructors of Lazy class. Lazy<T> allows Func<T> delegate as argument in some of its overloads.

In a multithreaded scenario:
In a multithreaded scenario the first thread using the lazy instance causes the initialization causes the initialization procedure and its value would be seen by the other threads. Although the other threads will also cause the initialization but their value will not be used. In a multithreaded scenario, like this, we can use any overload of EnsureInitialized method of Lazyintializer for even better performance. This can also use any of the default constructor or specialized constructor using Func delegate.

http://msdn.microsoft.com/en-us/library/system.threading.lazyinitializer.ensureinitialized.aspx

Download Code:

Thursday, February 24, 2011

Rx - Executing anonymous code asynchronously

In the previous post we discuss about how we can execute a method asynchronously using Reactive Extensions. In this post we will discuss how we can execute anonymous code asynchronously using Reactive Extensions. Rx provides this support using Observable.Start.

Invoking Actions (No data returned):
Let us start with discussing how we can execute code asynchronously with no data to return.


The event handler of Click event of the button is as follows:

private void button2_Click(object sender, RoutedEventArgs e)
{
Observable.Start(() =>
{
Thread.Sleep(2000);

return;
}
)
.ObserveOnDispatcher()
.Subscribe(
(result) => { ;},
(ex) => this.Background = Brushes.Red,
() => this.Background = Brushes.Green);
}

This code just executes simple code asynchronously in a ThreadPool thread. It generates OnNext, OnCompleted and OnError messages on the Dispatcher thread as we are observing on Dispatcher. After atleast two seconds the background of window should turn green.

Invoking anonymous code (data returned from lambda) asynchronously:
We can also execute anonymous asynchronous code using Observable.Start which actually return a value. This code is in the form of lambda expressions or lambda statements which explicitly return data through return statement. Let us add a button on the same window. When user clicks the button it should update the operand boxes with any random number.

private void btnFillRandomOperands_Click(object sender, RoutedEventArgs e)
{
Observable.Start<int>(
() =>
{
Thread.Sleep(2000);
return new Random().Next(1, 10);
}).ObserveOnDispatcher<int>()
.Subscribe(
(result) =>
{
this.textBoxOperand1.Text = result.ToString();
this.textBoxOperand2.Text = result.ToString();
},
(ex) => this.Background = Brushes.Red,
() => this.Background = Brushes.Green
);

}

The above code uses Random class to generate a random number between 1 and 10. The returned number is provided to OnNext handler by Rx runtime. This handler updates both operand text boxes with this number. After this, the runtime places OnCompleted handler which turns the background of the window to green.

When we run this and click this button, it results in the following window after atleast 2 seconds. Definitely, it might be a different random number generated and filled in the operands text boxes.



Passing Arguments to Code executed by Observable.Start:
It doesn’t seem that we can have any parameters to Observable.Start directly. But we can use our old technique of using Captured Variables. As we know that lambdas can capture variables from the scope they are generated from. The variables used by lambda like this are called Captured variables. Like a regular lambda statement executed asynchronously, these variables also have Closure issues. I have discussed here how to avoid closure issues by assigning the value of captured variables to local variables inside lambdas.

http://shujaatsiddiqi.blogspot.com/2010/12/wpf-dispatcherbegininvoke-and-closures.html

private void button1_Click(object sender, RoutedEventArgs e)
{
decimal operand1 = Decimal.Parse(this.textBoxOperand1.Text);
decimal operand2 = Decimal.Parse(this.textBoxOperand2.Text);

Observable.Start(() =>
{
Thread.Sleep(2000);

return operand1 + operand2;
})
.ObserveOnDispatcher()
.Subscribe(
(result) => { this.textBoxResult.Text = result.ToString(); });

operand1 = 3;
operand2 = 4;
}

In the above case what do you guess would be shown in the result textbox if we enter 2.1 and 3.5 in the two operand text boxes. If you guess 5.6 then you would be surprised to see this result.


This is the result of modified captured variables as the modified value of those captured variables are used which are 3 and 4. The result of addition of 3 and 4 is 7, which is displayed in the Result text box. In order to fix this, we can define two new local variables localOperand1 and localOperand2 and initialize them with the values of captured variables.

private void button1_Click(object sender, RoutedEventArgs e)
{
decimal operand1 = Decimal.Parse(this.textBoxOperand1.Text);
decimal operand2 = Decimal.Parse(this.textBoxOperand2.Text);

Observable.Start(() =>
{
decimal localOperand1 = operand1;
decimal localOperand2 = operand2;

Thread.Sleep(2000);

return localOperand1 + localOperand2;
})
.ObserveOnDispatcher()
.Subscribe(
(result) => { this.textBoxResult.Text = result.ToString(); });

Thread.Sleep(2);

operand1 = 3;
operand2 = 4;
}

When we run the application and enter data 2.1 and 3.5 then the correct result is displayed in the Result text box.


Although Resharper still shows warning but it is just fine as we have seen the correct result being calculated.


Observable.Start and Exceptions in the code executed:
As a result of an exception Observable.Start behaves same way as Observable.ToAsync. We can represent the behavior in marble diagram as follows:


Let us update the code executed asynchronously using Observable.Start so that if the sum of number entered is either zero or lesser, it should throw an Exception.

[DebuggerStepThrough]
private void button1_Click(object sender, RoutedEventArgs e)
{
decimal operand1 = Decimal.Parse(this.textBoxOperand1.Text);
decimal operand2 = Decimal.Parse(this.textBoxOperand2.Text);

Observable.Start(() =>
{
decimal localOperand1 = operand1;
decimal localOperand2 = operand2;
decimal sum = localOperand1 + localOperand2;

Thread.Sleep(2000);

if (sum <= 0)
{
throw new System.Exception("Error in computation");
}

return sum;
})
.ObserveOnDispatcher()
.Subscribe(
(result) => { this.textBoxResult.Text = result.ToString(); },
(ex) => this.Background = Brushes.Red,
() => this.Background = Brushes.Green);

}

You can notice that we are still subscribing on Dispatcher. In addition to OnNext, we have provided the code for OnCompleted and OrError. The window should turn green when the operation completed successfully resulting in OnCompleted. In case of exception, OnError is executed.



Using IScheduler to run Asynchronous code:
Like Observable.ToAsync, Observable.Start also provides overloads to run the asynchronous code using different IScheduler. We can run code which returns or does not return any data in the form of lambda and we can run it using the IScheduler of our choice. You can see that just by providing Scheduler.Dispatcher info to Start we can turn this method to run on UI thread:

Observable.Start(() =>
{
Thread.Sleep(2000);

return;
}, Scheduler.Dispatcher
)

Note:
There is one more overload of Observable.Start which returns ListObservable<TSource>. Since it is not about executing anonymous asynchronous code, we are discussing it here.

Download Code:

Wednesday, February 23, 2011

WPF - ASynchronous Function using Observable.ToASync [Rx ASynchronous Delegate] - Part # 2

This is the second part of our discussion about how we can execute the similar functionality as provided by asynchronous anonymous delegates in .net. In previous post we discuss how we can mimic the functionality provided by Func<...> delegate.

http://shujaatsiddiqi.blogspot.com/2011/02/wpf-asynchronous-function-using.html

In this post we will discuss about Action<...> delegate. As we know that we can not return any value from this compared to Func<...> delegate. As we know that .net provides 16 different generic overloads of Action<...> delegates in order to accommodate delegates for methods having up to 16 parameters. Similarly, 16 different overloads of Observable.ToAsync have been provided.

Let us add this method to our class:

[DebuggerStepThrough]
private void ProcessOperandsFireAndForget(decimal operand1, decimal operand2)
{
Thread.Sleep(5000);
if (operand1 <= 0 || operand2 <= 0)
{
throw new System.Exception("Exception generated");
}
}

Since it returns void, we can use Action delegate for this. In Reactive Extension we can use Observable.ToAsync for this method. It just producing a delay of 5 seconds. If any of the operands are zero or negative, it is resulting in an exception with message "Exception generated".

In order to run this we add another button on the window. The handler for Click event for the button can be as follows:

private void btnFireAndForget_Click(object sender, RoutedEventArgs e)
{
decimal operand1 = Decimal.Parse(this.textBoxOperand1.Text);
decimal operand2 = Decimal.Parse(this.textBoxOperand2.Text);

Observable.ToAsynclt;decimal, decimal>(ProcessOperandsFireAndForget, Scheduler.TaskPool)(operand1, operand2)
.ObserveOnDispatcher()
.Subscribe<Unit>(
(result) => { ; },
(ex) => this.Background = Brushes.Red,
() => this.Background = Brushes.Green);

}

Before running this code, let me explain the expected behavior. Basically you should be expecting the same behavior as of a method which actually returns a value. We can see that from marble diagram:

Graceful method execution:



Exception in method execution:


Now one thing is of interest which you might have already noticed. It is about OnNext message. Since OnNext passes some data in its argument, what data runtime would be passing in this as this method has void return type. Just to clarify this, I have used a generic overload of Subscribe method. See Unit type there? Basically is a new IEquatable struct provided in .net framework. Basically the message is generated. For methods with no return types, OnNext messages are generated with this type.



IScheduler support for Observable.ToAsync:
As I have told you that various overloads have been provided for Observable.ToAsync have been provided to accommodate all different overloads of Func and Action delegates. Make it at least double. Basically with each overload provided to support a particular number of arguments, one overload is provided to support an IScheduler so that we could decide which IScheduler to use to run this asynchronous code. Using these overloads we can specify which Scheduler we want to use to execute the method. Whatever thread is used to execute the method, would be the same thread on which OnNext, OnCompleted and OnError messages are generated.

Note:
We can also execute methods without any parameters with / without any return type using Observable.ToAsync. It would be following the same marble diagrams as presented in this post.

Download Code:

Tuesday, February 22, 2011

WPF - ASynchronous Function using Observable.ToASync [Rx ASynchronous Delegate] - Part # 1

This is the first part of our discussion about asynchronous method execution using Reactive Extension. The second part of this discussion can be found here:

http://shujaatsiddiqi.blogspot.com/2011/02/wpf-asynchronous-function-using_23.html

In this post we discuss how we can execute a method asynchronously using the features provided in Reactive Extensions Rx. We discussed the usage of asynchronous delegate in a WPF application in the following post:

http://shujaatsiddiqi.blogspot.com/2010/12/asynchronous-delegate-exception-
model.html

This is basically the similar concept in Rx.

<Window x:Class="WpfApp_AsynchObserver.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBox Height="27" HorizontalAlignment="Left" Margin="138,22,0,0"
Name="textBoxOperand1" VerticalAlignment="Top" Width="311" />
<TextBox Height="27" HorizontalAlignment="Left" Margin="138,55,0,0"
Name="textBoxOperand2" VerticalAlignment="Top" Width="311" />
<TextBox Height="27" HorizontalAlignment="Left" Margin="138,143,0,0"
Name="textBoxResult" VerticalAlignment="Top" Width="311" />
<Button Content="Sum" Height="28" HorizontalAlignment="Left" Margin="139,88,0,0"
Name="button1" VerticalAlignment="Top" Width="143" Click="button1_Click" />
<Label Content="Operand 1" Height="27" HorizontalAlignment="Left" Margin="12,22,0,0"
Name="label1" VerticalAlignment="Top" Width="120" />
<Label Content="Operand 2" Height="27" HorizontalAlignment="Left" Margin="12,55,0,0"
Name="label2" VerticalAlignment="Top" Width="120" />
<Label Content="Result" Height="27" HorizontalAlignment="Left" Margin="12,143,0,0"
Name="label3" VerticalAlignment="Top" Width="120" />
</Grid>
</Window>


The code behind is as follows:

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private decimal ProcessOperands(decimal operand1, decimal operand2)
{
decimal sum;
sum = operand1 + operand2;

return sum;
}

private void button1_Click(object sender, RoutedEventArgs e)
{
decimal operand1 = Decimal.Parse(this.textBoxOperand1.Text);
decimal operand2 = Decimal.Parse(this.textBoxOperand2.Text);

this.textBoxResult.Text = ProcessOperands(operand1, operand2).ToString();
}
}

Lets run the application now. Everything is working great. We enter numeric digits in the two operands fields. When we click Enter, the result appears in the Result text box. Now let us change the method call (ProcessOperands) to be an asynchronous call using Observable.ToAsync. We need to update the button’s click handler as follows:

private void button1_Click(object sender, RoutedEventArgs e)
{
decimal operand1 = Decimal.Parse(this.textBoxOperand1.Text);
decimal operand2 = Decimal.Parse(this.textBoxOperand2.Text);

Observable.ToAsync<decimal, decimal, decimal>(ProcessOperands)(operand1, operand2)
.Subscribe(
(result) => { this.textBoxResult.Text = result.ToString(); }
);
}

The code clearly shows that we have used an overload of ToAsync which takes two decimal values as arguments and returns a decimal value. We have used this as our ProcessOperand method is defined like that. You can see that we have used the value provided in the onNext parameter to populate the textBoxResult. Basically onNext is placed when the async code is finished execution and result is available. If we compare it to the code we have written for Asynchronous delegates, we realize that Rx has internally executed code for BeginInvoke and also called EndInvoke for us getting the result using IAsyncResult. If we look at the marble diagram, it should be like this.



In the marble diagram, this has shown to be placing an OnCompleted message afterwards. Let us verify that this event is generated. In the following code, we are updating the Background color to green when OnCompleted message is received from the Observable generated for the method.

private void button1_Click(object sender, RoutedEventArgs e)
{
decimal operand1 = Decimal.Parse(this.textBoxOperand1.Text);
decimal operand2 = Decimal.Parse(this.textBoxOperand2.Text);

Observable.ToAsync<decimal, decimal, decimal>(ProcessOperands)(operand1, operand2)
.Subscribe(
(result) => { this.textBoxResult.Text = result.ToString(); },
() => this.Background = Brushes.Green
);
}

Now we run the application and enter values in the operands text boxes. When we click the button, the textBoxResult is updated with the sum of two operands. The window also turns green. This is due to the code we have written in OnCompleted handler.



Long running methods and Rx Thread Management for generating asynchronous block:
Now you might be thinking that this is a very simple example. What if the method is a long running method taking a few seconds. Would it still be the same code. Let’s mimic that this method is taking a few seconds by putting Thread.Sleep in method code as follows:

private decimal ProcessOperands(decimal operand1, decimal operand2)
{
decimal sum;
sum = operand1 + operand2;

Thread.Sleep(5000);
}

If you run this and enter data in the input text boxes and click Sum. You get the following exception:



Why is this exception generated by just delaying in the asynchronous method? Basically we have caused the subscription to be on a ThreadPool thread. Since we are delaying for 5 seconds, all Rx messages (OnNext, OnCompleted and OnError) seem to be dispatched on the calling thread of subscriber.

It seems if there is a delay of more than 3 milliseconds then the OnNext messages are dispatched on a ThreadPool thread otherwise they are dispatched on the thread of the subscriber. In this case it is UI thread. If the delay is 3 milliseconds or lesser these messages are always dispatched on UI thread. This is true even though we know that ToAsync is causing the method to be executed on a ThreadPool thread.

Fig: When OnNext is received in more than 3 milliseconds:



Fig: When OnNext is received in 3 milliseconds or less:



How exceptions are handled?

As we have discussed [http://shujaatsiddiqi.blogspot.com/2010/12/asynchronous-delegate-exception-model.html] the runtime is silent about exceptions for Async delegates if we don’t call EndInvoke. It is not the case with Observable.ToAsync. It always generate exception message OnError when there is an exception in the method executed asynchronously. Let us change the code of ProcessOperands so that it throws an exception.

[DebuggerStepThrough]
private decimal ProcessOperands(decimal operand1, decimal operand2)
{
decimal sum;
sum = operand1 + operand2;

if (sum < 0)
{
throw new System.Exception("Exception in processing data!");
}

return sum;
}

The above code is resulting an exception if the sum of these two operands is negative. We also need to update the code so that IObservable generated from Observable.ToAsync has a non-default OnError handler. I have decorated the method with DebuggerStepThrough attribute so that Debugger doesn’t bother me as I have FCEs turned on. Let’s update button1_Click as follows:

private void button1_Click(object sender, RoutedEventArgs e)
{
decimal operand1 = Decimal.Parse(this.textBoxOperand1.Text);
decimal operand2 = Decimal.Parse(this.textBoxOperand2.Text);

Observable.ToAsync<decimal, decimal, decimal>(ProcessOperands)(operand1, operand2)
.Subscribe(
(result) => { this.textBoxResult.Text = result.ToString(); },
(ex) => this.Background = Brushes.Red,
() => this.Background = Brushes.Green
);
}

It just changes the background of the window to Red if there is an OnError message from the method. Let’s run the application and enter data 2 and -5 in the operand fields. As we know that their sum is -3, the background of the window should turn Red.


We can show this in marble diagram as follows:



Observing on Non-UI thread using different IScheduler:

Now we suppose that the method would always take more than 3 milliseconds. Can we still use ToAsync feature of Observable? Yes we can!

We just need to Observe on the Dispatcher. This can be done by using ObserveOn feature of IObservable. There are two methods provided for this purpose. One method allows us to generate the messages on any IScheduler (including built-in schedulers like Dispatcher, ThreadPool, TaskPool, Immediate, CurrentThread, NewThread). We can use any of the four overloads of this method. We can also directly use ObserveOnDispatcher method from IObservable. We have used the same as below.

private void button1_Click(object sender, RoutedEventArgs e)
{
decimal operand1 = Decimal.Parse(this.textBoxOperand1.Text);
decimal operand2 = Decimal.Parse(this.textBoxOperand2.Text);

Observable.ToAsync<decimal, decimal, decimal>(ProcessOperands)(operand1, operand2)
.ObserveOnDispatcher<decimal>()
.Subscribe(
(result) => { this.textBoxResult.Text = result.ToString(); },
(ex) => this.Background = Brushes.Red,
() => this.Background = Brushes.Green
);
}

Now we run the application. Although the method is being executed on a separate ThreadPool thread but the OnNext, OnError and OnCompleted messages are dispatched on UI thread.

Fig: Method executed on a ThreadPool thread


Fig: OnNext message generated on Main UI Thread


Fig: OnCompleted placed on Main UI thread


Fig: OnError placed on Main UI thread



Limitations:
Since this is a way to implement Anonymous asynchronous delegates using Reactive Extensions so it seems to have has the same limitation as anonymous asynchronous delegate (Func) has. We can not have out or ref parameters in the method that we want to execute asynchronously. In non-reactive model, we might easily implement named asynchronous delegate as a work around but in the reactive extension world there doesn't seem to be any alternative.

Download Code:

Saturday, December 11, 2010

WPF - ASynchronous Delegate Exception Model

In this post, we are going to discuss exception model of Asynchronous delegates. For those who have started development just starting with .net 4.0, they are old school for Task. Basically thread (including ThreadPool.QueueUserWorkItem based threads) are for providing "shoot and run" kind of flows. They don't us allow to return anything from them. If we needed to return a value, the only option we have is ASynchronous Delegate. It must be remembered that Asynchronous delegate would still be using ThreadPool thread so it will have all the benefits of using a ThreadPool thread.

Like BackgroundWorker, ASynchDelegate also has a special mechanism for dealing with exceptions raised during its operation. It is necessary to be aware of it. We will be discussing the use of ASynchDelegate in a sample WPF application. In this application, we will be taking input of two operands. The application would perform some complex calculation on these operands and display the result on the form. In order to keep the example simple, we would just sum these operands. We will not be verifying the inputs just for the same reason.


The XAML for the above display is as follows:

<Window x:Class="WpfApplication_ASynchDelegate.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WindowASynchDelegate" Height="389" Width="595">
<Grid>
<TextBox Height="27" HorizontalAlignment="Left" Margin="138,22,0,0"
Name="textBoxOperand1" VerticalAlignment="Top" Width="311" />
<TextBox Height="27" HorizontalAlignment="Left" Margin="138,55,0,0"
Name="textBoxOperand2" VerticalAlignment="Top" Width="311" />
<TextBox Height="27" HorizontalAlignment="Left" Margin="138,143,0,0"
Name="textBoxResult" VerticalAlignment="Top" Width="311" />
<Button Content="Sum" Height="28" HorizontalAlignment="Left" Margin="139,88,0,0"
Name="button1" VerticalAlignment="Top" Width="143" Click="button1_Click" />
<Label Content="Operand 1" Height="27" HorizontalAlignment="Left" Margin="12,22,0,0"
Name="label1" VerticalAlignment="Top" Width="120" />
<Label Content="Operand 2" Height="27" HorizontalAlignment="Left" Margin="12,55,0,0"
Name="label2" VerticalAlignment="Top" Width="120" />
<Label Content="Result" Height="27" HorizontalAlignment="Left" Margin="12,143,0,0"
Name="label3" VerticalAlignment="Top" Width="120" />
</Grid>
</Window>

The code behind of the above window is as follows:

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private decimal getSum(decimal operand1, decimal operand2)
{
decimal sum;
sum = operand1 + operand2;

return sum;
}

private void button1_Click(object sender, RoutedEventArgs e)
{
decimal operand1 = Decimal.Parse(this.textBoxOperand1.Text);
decimal operand2 = Decimal.Parse(this.textBoxOperand2.Text);

Func<decimal, decimal, decimal> getSumAsynchDelegate = getSum;

getSumAsynchDelegate.BeginInvoke(operand1, operand2,
(resultASynch) =>
{
var methodDelegate = (Func<decimal, decimal, decimal>)resultASynch.AsyncState;

this.Dispatcher.BeginInvoke(
new Action(() =>
this.textBoxResult.Text =
methodDelegate.EndInvoke(resultASynch).ToString()));
},
getSumAsynchDelegate);
}
}

In the Click event handler for the button, we have assigned the text entered in two input text boxes texBoxOperand1 and textBoxOperand2 to local variables operand1 and operand2. We have introduced an asynchronous delegate. This is expected to receive two decimal arguments and returns a decimal value. In the Asynchronous delegate declaration, the last value specified is the return type.

Func<decimal, decimal, decimal> getSumAsynchDelegate = getSum;

Although Asynchronous delegate seems to be similar to the Asynchronous methods (Asynchronous Programming Model - APM) because It has BeginInvoke and EndInvoke mechanism as in ASynchronous method and BeginInvoke returns IASynchResult as ASynchronous methods. But it must be remembered that BeginInvoke returns immediately after calling the method to the calling method. As discussed here, we can call BeginInvoke to invoke an Asynchronous delegate. It seems that we have provided four arguments to it. First two are for the method parameters [It depends on how many parameters you have for the method being called]. The third argument is the callback after the method finishes execution on a different thread. The last parameter is anything we want to pass. It is copied to ASynchState of the method. We can get this value in the callback. We have passed the delegate itself to ASynchState as we don't want to declare an instance member for it.

Now we discuss the lambda for the callback which gets called when asynchronous delegate finishes execution.

(resultASynch) =>
{
var methodDelegate = (Func<decimal, decimal, decimal>)resultASynch.AsyncState;

this.Dispatcher.BeginInvoke(
new Action(() =>
this.textBoxResult.Text =
methodDelegate.EndInvoke(resultASynch).ToString()));
},

As you can see, we have obtained the delegate from ASynchState property of resultASynch(IASynchResult). The interesting thing to notice is that we have used Dispatcher to copy value to textBoxResult.Text. This is because, unlike BackgroundWorker, the callback is not executed on UI thread. In order to get the returned value from the delegate, we need to call EndInvoke on the delegate passing IASynchResult as the argument. Since the method is expected to return a decimal value, we are converting it to string before assigning to the Text property of the text box.

Even if we don't call EndInvoke on ASynchronous Delegate, it still would finish execution. It wouldn't be making sense to use this delegate though in this kind of situation, as we are not expecting any returned value. But if we don't call EndInvoke then we lose any exception caused in the method called using asynchronous delegate. It is a silent exception. This is the same thing as we discussed in BackgroundWorker. We must be aware of all these silent failures in our application as it can lead our application to be in an unexpected state.

Let's update the method as follows:

[DebuggerNonUserCode]
private decimal getSum(decimal operand1, decimal operand2)
{
decimal sum;
sum = operand1 + operand2;

if (sum > 0)
throw new Exception("What did u do!");

return sum;
}

So if we don't call EndInvoke and update the definition of the method and don't call EndInvoke, the application would never know about the exception. If we don't use try / catch block with EndInvoke and the method results in an exception, the exception could end up in DispatcherUnhandledException if we are calling EndInvoke on a UIThread. Or AppDomain.CurrentDomain.UnhandledException if we are calling it in any other thread (as in the callback of asynchronous delegate).