WPF: Asynchronous Data Binding Using IsAsync and Delay

** 
**
**
**

INTRODUCTION: IsAsync

Most system designs will mean that data needs to be obtained from a view using it is presented.  If this is a long process, a common technique is to present a busy indicator whilst data is collected.  The View might be presented bare, the busy indicator is hidden and the data presented once it arrives.
Occasionally, part of the content might not be critical and it might be attractive to obtain most of the data, show the view and later add the lower priority data.
A classic sort of an example of this pattern would be how some web pages download text and show it, only later presenting images. 

WPF has the IsAsync property for a binding.  The effect is that the binding doesn't wait for a value to be returned from the bound property getter before continuing.
The get is called and control immediately returns. 

Images are a "classic" area where one would use IsAsync. 

There is no free meal here though and the object must either not have thread affinity or be coerced to the UI thread, PropertyChanged event must be raised on the UI thread. Whilst the property has not been provided, usual rules also apply on the binding and it will return null. You can, therefore, show an initial default value using FallBackValue.

DEMO: Synchronous binding

Here is the .cs file.

public partial  class AsyncBinding : UserControl, INotifyPropertyChanged
    {
        public AsyncBinding()
        {
            InitializeComponent();
        }
  
  
        #region INotifyPropertyChanged Members
  
        public event  PropertyChangedEventHandler PropertyChanged;
        public void  OnPropertyChanged(string txt)
        {
  
            PropertyChangedEventHandler handle = PropertyChanged;
            if (handle != null)
            {
                handle(this, new  PropertyChangedEventArgs(txt));
            }
        }
        #endregion
  
        private string  firstname;
  
        public string  FirstName
        {
            get { return firstname; }
            set
            {
                firstname = value;
                OnPropertyChanged("FirstName");
            }
        }
        private string  address;
  
        public string  Address
        {
            get
            {
                Thread.Sleep(5000);
                return address;
            }
            set
            {
                Thread.Sleep(5000);
                address = value;
                OnPropertyChanged("Address");
            }
        }
  
        private string  phone;
  
        public string  Phone
        {
            get { return phone; }
            set
            {
                phone = value;
                OnPropertyChanged("Phone");
            }
        }
  
        private void  ThisWindow_Loaded(object sender, RoutedEventArgs e)
        {
            FirstName = "Ryan";
            Address = "USA";
            Phone = "4563525234523";
        }
  
       
  
    }

Inside addresses set/get a block in Thread.Sleep(). While running the application, we can see a delay in loading the elements in the UI.

DEMO: IsAsync

Added IsAsync= true inside address property binding. See the result.

 

 

Initial state

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

After 5000 milliseconds.

INTRODUCTION: Delay

Delay simply introduces a delay before the getter is called.  It is often used to spread processing load or (rarely) where you know in advance a value will vary rapidly for a short period of time. 
In some cases, you might have some 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.

DEMO: Delay

For a delay demonstration, we 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. We have added one delay inside the address property highlighted in the image below.

private string  address;
 
     public string  Address
     {
         get
         {
            // Thread.Sleep(5000);
             return address;
         }
         set
         {
           //  Thread.Sleep(5000);
             address = value;
             OnPropertyChanged("Address");
         }
     }

   

Once we type into the address1 text box, that will wait for 500 milliseconds to reflect the changes. After that time address2 will be populated.

Initial state

After 500 milliseconds

Conclusion

Two alternative mechanisms for asynchronous binding have been presented: IsAsync mainly for binding large resources and Delay is used to avoid calling downstream logic too soon for rapidly changing values.