Click here to Skip to main content
Click here to Skip to main content

Tagged as

Threads in WPF

, 28 Aug 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
It will include implementation and usage of thread in WPF application.

Introduction

Threading enables program to perform concurrent processing so that it can do more than one operation at a time. WPF (Window Presentation Foundation) has been designed in a way that saves developer from the difficulties of threading. This article can help to understand the proper usages of threading in WPF.

WPF Internal threads and rules

All WPF application runs with two threads:

  1. For rendering - It runs in the background so, it is hidden.
  2. For managing UI interface (UI thread) –

Most of the WPF objects are tied with UI threads. It receives input, paints the screen, runs code and handles events.

WPF supports a single-threaded apartment model which has following rules:

  1. One thread runs in the entire application and own all WPF objects.
  2. WPF elements have thread affinity means other thread can’t interact with each other.
  3. WPF objects that have thread affinity derive from Dispatcher object.

Thread handling in WPF by developer

While creating application in WPF developer need to manage threads in some case so, it provides some ways to handle and use thread in the application on different scenarios. Following are the two ways for the handling threads:

  1. The Dispatcher
  2. The Background Worker.

The Dispatcher

The Dispatcher is an instance of the System.Windows.Threading. Dispatcher class. It owns the application thread and manages queue of work item. It executes UI operations in FIFO (First in First Out) manner by taking priority of each. It does not creates new thread. It is not multi-threaded.

Every Visual WPF objects derive from DispatcherObject. It is an object that is linked to DispatcherObject class. Following are the members of DispatcherObject class:

 (1) Properties

  1. Dispatcher:  It gets Dispatcher.

(2) Methods:

  There are several methods in the DispatcherObject Class. Some important methods are below:

  1. CheckAccess (): It returns true if code is one the right thread to use the object.
  2. VerifyAccess (): Does nothing if the code is on the right thread to use the object otherwise throws and “InvalidOperationException”.
  3. GetType (): It gets the type of current instance.

 WPF objects call VerifyAccess () frequently to project themselves.

Why do we need Dispatcher?

An example that will clarify the need of Dispatcher in WPF Application:

using System;
using System.Threading;
using System.Windows;

namespace WpfApplication1
{
   /// <summary>
   /// Interaction logic for WPF UI Upadation using
   /// thread.
/// </summary>

   public partial class MainWindow : Window
    {

       public MainWindow()
        {
           InitializeComponent();
        }

        private void MyButton_Click(object sender, RoutedEventArgs e)
         {
            Thread thread = new Thread(UpdateText);
            thread.Start();
         }

      private void UpdateText()
        {
            Thread.Sleep(TimeSpan.FromSeconds(5));
            TxtName.Text = "Hello Geeks !";
        }
     }
}

 

Now, this is a wrong code because UpdateText() method will be executed on a new thread, and that thread is not allowed to access WPF objects.

Method “VerifyAccess()” calls and “InvalidOperationException” is thrown.

For the correction of above code:

using System;
using System.Threading;
using System.Windows;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for WPF UI Upadation using
    /// Dispatcher.
    /// </summary>

    public partial class MainWindow : Window
     {
        public MainWindow()
         {

            InitializeComponent();
         }

        private void MyButton_Click(object sender, RoutedEventArgs e)
         {

            Thread thread = new Thread(UpdateText);
            thread.Start();
         }

        private void UpdateText()
	 {
	     Thread.Sleep(TimeSpan.FromSeconds(5));
	     this.Dispatcher.BeginInvoke(new Action(() =>
		{
		   TxtName.Text = "Hello Geeks !";
		}));
	}
      }
}

So, Dispatcher is the best way for updating WPF UI with thread.

 

The Background Worker

It is very beneficial in time-consuming tasks. It executes the code at the same time. It is invoked in a separate thread. It automatically synchronizes with main thread of an application.

It is used to run an operation in the background and defer execution to the UI. Following are the some cases where Background worker can be used:

  1. If user wants a responsive UI and faces delays in a particular operations.
  2. Data download.
  3. Database transactions.

 

BackgroundWorker is class under System.ComponentModel. It executes operation on a separate thread.

using System;
using System.ComponentModel;
using System.Threading;

namespace BackGroundWorkerExample
{

    /// <summary>
    /// It implements backgroundworker.
    /// </summary>

    class Program
     {

        private static BackgroundWorker backgroundWorker;
        static void Main(string[] args)
          {
             backgroundWorker = new BackgroundWorker
  		{
		    WorkerReportsProgress = true,
		    WorkerSupportsCancellation = true
		};

            //Event creation.

            //For the performing operation in the background.

            backgroundWorker.DoWork += backgroundWorker_DoWork;

            //For the display of operation progress to UI.

            backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;

            //After the completation of operation.

            backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;

            backgroundWorker.RunWorkerAsync("Press Enter in the next 5 seconds to Cancel operation:");

            Console.ReadLine();

            if (backgroundWorker.IsBusy)
		{
 		   backgroundWorker.CancelAsync();
		   Console.ReadLine();
		}
}

 Now, Perform operation in the background.    

/// <summary>
/// Performs operation in the background.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>

static void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
  {

	for (int i = 0; i < 200; i++)
	   {
		if (backgroundWorker.CancellationPending)
		   {
			e.Cancel = true;
			return;
	           }

               backgroundWorker.ReportProgress(i);
	       Thread.Sleep(1000);
	       e.Result = 1000;
           }
}

 

Perform operation for the Progress changes event.

/// <summary>
/// Displays Progress changes to UI .
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>

static void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    Console.WriteLine("Completed" + e.ProgressPercentage + "%");
}

 

Display result by using Runworker completed event :

/// <summary>
/// Displays result of background performing operation.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>

static void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  {
	if (e.Cancelled)
	   {
	        Console.WriteLine("Operation Cancelled");
           }
	else if (e.Error != null)
	   {
	        Console.WriteLine("Error in Process :" + e.Error);
	   }
	 else
	   {
                Console.WriteLine("Operation Completed :" + e.Result);
	   }

  }

 

Output:

Completed 0%

Completed 1%

Completed 2%

..........................

 

Difference between Dispatcher and Background Worker:

  1. Background worker executes the code at the same time it is invoked in a separate thread. It automatically synchronizes with main thread of WPF application while Dispatcher processes a queue of things to do every time.
  2. Background worker executes in the separate thread while dispatcher runs with UI thread of WPF application.
  3. If you want to run an operation in the background to the UI, use a background worker but use the Dispatcher to marshal update back to the WPF UI.

 

References:

Book: Illustrated WPF by Daniel Solis.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Gul Md Ershad
Software Developer (Senior) Infosys
India India
No Biography provided

Comments and Discussions

 
GeneralMy vote of 2 PinprotectorPete O'Hanlon29-Aug-14 0:18 
GeneralRe: My vote of 2 Pinmemberogauchard29-Aug-14 6:05 
GeneralRe: My vote of 2 PinprotectorPete O'Hanlon29-Aug-14 7:38 
Generalwpf thread PinmemberMember 1104441428-Aug-14 20:28 
QuestionWell done sir Pinmembersachinohri28-Aug-14 20:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.1411022.1 | Last Updated 28 Aug 2014
Article Copyright 2014 by Gul Md Ershad
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid