Friday, June 24, 2011

WPF -Multithreading in WPF

Multithreading means executing more than one code block at a time .Usually it is used to create more responsive user interface(User interface that is not freezed up) ,although it can be used for other tasks as well like performing some action while still waiting for a response from web service.


In this article i will show how to create multithreading in wpf.


Step 1
Create a WPF Application and give the solution name as WpfMultiThreading.


Step 2
Add a three textbox and single button control on window,it is look like this

 <Grid>
        <TextBox Height="23" HorizontalAlignment="Left" Margin="48,60,0,0" Name="txtXAML" IsReadOnly="True" VerticalAlignment="Top" Width="120" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="185,60,0,0" Name="txtWPF" IsReadOnly="True" VerticalAlignment="Top" Width="120" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="320,60,0,0" Name="txtSilverlight" IsReadOnly="True" VerticalAlignment="Top" Width="120" />
        <Button Content="OK" Height="23" HorizontalAlignment="Left" Margin="214,163,0,0" Name="btnOk" VerticalAlignment="Top" Width="75" Click="btnOk_Click" />
    </Grid>



Click on Image for better view

Step 3
MultiThread Process


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;

namespace WpfMultiThreading
{
    /// 
    /// Interaction logic for MainWindow.xaml
    /// 
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        /// 
        /// Threads Execute
        /// 
        /// 



        /// 



        private void btnOk_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                Thread ThreadXAML = new Thread(new ThreadStart(BindXAML));
                ThreadXAML.Start();

               
                Thread ThreadWPF = new Thread(new ThreadStart(BindWPF));
                ThreadWPF.Start();

               
                Thread ThreadSilverlight = new Thread(new ThreadStart(BindSilverlight));
                ThreadSilverlight.Start();
 
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);  
            }
        }

        #region Method

        private void BindXAML()
        {
            try
            {
                lock (this)
                {
                    this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                        new Action(
                                delegate
                                {
                                    try
                                    {
                                        this.txtXAML.Text = "XAML";
                                    }
                                    catch (Exception ex)
                                    {
                                        MessageBox.Show(ex.Message);
                                    }
                                }
                            )
                        );
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);  
            }
        }

        private void BindWPF()
        {
            try
            {
                lock (this)
                {
                    this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                        new Action(
                                delegate
                                {
                                    try
                                    {
                                        this.txtWPF.Text = "WPF";
                                    }
                                    catch (Exception ex)
                                    {
                                        MessageBox.Show(ex.Message);
                                    }
                                }
                            )
                        );
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void BindSilverlight()
        {
            try
            {
                lock(this)
                {
                    this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                        new Action(
                                delegate
                                {
                                    try
                                    {
                                        this.txtSilverlight.Text = "Silverlight";
                                    }
                                    catch (Exception ex)
                                    {
                                        MessageBox.Show(ex.Message);
                                    }
                                }
                            )
                        );
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


        #endregion
    }
}

The Above Code Creates a Multipal Threads which tries to bind a text in three textboxs on button click Event.

Lock Statement
lock ensures that one thread does not enter a critical section while another thread is in the critical section of code. If another thread attempts to enter a locked code, it will wait (block) until the object is released.


Dispatcher

The Dispatcher class provides a gateway to the message pump in WPF and provides a mechanism to route work for processing by the UI thread. This is necessary to meet the thread affinity demands, but since the UI thread is blocked for each piece of work routed through the Dispatcher, it is important to keep the work that the Dispatcher does small and quick. It is better to break apart larger pieces of work for the user interface into small discrete blocks for the Dispatcher to execute. Any work that doesn't need to be done on the UI thread should instead be moved off onto other threads for processing in the background.
Typically you will use the Dispatcher class to send worker items to the UI thread for processing.



Action Delegate
we can use the Action delegate to pass a method as a parameter without explicitly declaring a custom delegate. The encapsulated method must correspond to the method signature that is defined by this delegate. This means that the encapsulated method must have no parameters and no return value.
When you use the Action delegate, you do not have to explicitly define a delegate that encapsulates a parameterless procedure.


Dispatcher.Invoke()
The call to Invoke needs to take a few pieces of information. First is the priority you'd like your work executed with. Next is the delegate that contains the work you actually want to do. If your delegate takes parameters, the Invoke call will also accept an Object or Object[] to pass into the delegate function.




Run the Project.


Download
Download Source Code

1 comment: