Asynchronous Data Binding Using IsAsync and Delay in WPF

In this article we will learn about asynchronous data binding using IsAsync and Delay in WPF.

Introduction 

Normally data flows between a source and target will be fast enough when done in a synchronous manner on a UI thread by default, but in some cases you might have some resources, like fetching a large amount of data from a database or binding a large image and so on, that will be slow. Here is the purpose of asynchronous binding. In WPF, the source object can raise a PropertyChanged event on a separate thread. The binding can call a get/set block on a background thread by making IsAsync = true on binding.

Demo

Let me demonstrate synchronous binding first.

Here is the cs file.

  1. public partial class AsyncBinding : UserControl, INotifyPropertyChanged  
  2. {  
  3.     public AsyncBinding()  
  4.     {  
  5.         InitializeComponent();  
  6.     }  
  7.     #region INotifyPropertyChanged Members  
  8.     public event PropertyChangedEventHandler PropertyChanged;  
  9.     public void OnPropertyChanged(string txt)  
  10.     {  
  11.   
  12.         PropertyChangedEventHandler handle = PropertyChanged;  
  13.         if (handle != null)  
  14.         {  
  15.             handle(thisnew PropertyChangedEventArgs(txt));  
  16.         }  
  17.     }  
  18.     #endregion  
  19.     private string firstname;   
  20.     public string FirstName  
  21.     {  
  22.         get { return firstname; }  
  23.         set  
  24.         {  
  25.             firstname = value;  
  26.             OnPropertyChanged("FirstName");  
  27.         }  
  28.     }  
  29.     private string address;   
  30.     public string Address  
  31.     {  
  32.         get  
  33.         {  
  34.             Thread.Sleep(5000);  
  35.             return address;  
  36.         }  
  37.         set  
  38.         {  
  39.             Thread.Sleep(5000);  
  40.             address = value;  
  41.             OnPropertyChanged("Address");  
  42.         }  
  43.     }  
  44.     private string phone;  
  45.     public string Phone  
  46.     {  
  47.         get { return phone; }  
  48.         set  
  49.         {  
  50.             phone = value;  
  51.             OnPropertyChanged("Phone");  
  52.         }  
  53.     }  
  54.     private void ThisWindow_Loaded(object sender, RoutedEventArgs e)  
  55.     {  
  56.         FirstName = "Ryan";  
  57.         Address = "USA";  
  58.         Phone = "4563525234523";  
  59.     }  
  60. }  
Inside the address's set/get block there is a Thread.Sleep(). When running the application, we can see a delay for loading the elements in the UI. Let me change the synchronous binding to asynchronous binding.

Demo:IsAsync

I have added IsAsync= true inside the address property binding. See the result.

initialstate

Intial state

Initially we got data in all fields except address without any delay. After a few seconds the address field has been populated in the different thread.

after 5000 milliseconds

After 5000 milliseconds.

Delay

It is used to avoid calling downstream logic too soon for rapidly changing values. In some cases you might have several logic inside a set block of a property that is bound to a TextBox.Text property . That logic will be called when the user enters each character if UpdateSourceTrigger=PropertyChanged.

For a delay demonstration, I have commented the Thread.Sleep() in the get/set block of the address property and in the XAML we can see our address property bound with two Text Boxes. I have added one delay inside the address property that is highlighted in the image below.

  1. private string address;   
  2. public string Address  
  3. {  
  4.     get  
  5.     {  
  6.        // Thread.Sleep(5000);  
  7.         return address;  
  8.     }  
  9.     set  
  10.     {  
  11.       //  Thread.Sleep(5000);  
  12.         address = value;  
  13.         OnPropertyChanged("Address");  
  14.     }  
  15. }  
 
 
Once we type into the address1 text box, it will wait for 500 milliseconds to reflect the changes. Then the time address2 will be populated.



Initial state



After 500 milliseconds.