Building Responsive UI using Async Await in C#

Why build responsive UI? Answer seems obvious that end-user should experience that application doesn’t hang often (for developers POV, a time taking background operation makes it look like hanging). So lets learn building responsive UI using Async Await keywords

Visual Studio 2012 introduced a simplified approach, async programming, that leverage asynchronous support in the .NET Framework 4.5 and the Windows Runtime. The compiler does the difficult work that the developer used to do, and your application retains a logical structure that resembles synchronous code. This is extract from MSDN

Source Code was in written Visual Studio 2015 Community Edition, WPF, C#, .NET 4.5 on Windows 7 OS. However it can be used with Visual Studio 2013/2012(any version) on Windows 8, Windows 10 also.

Building Responsive UI using Async Await in C#

A simple WPF application which reads 12MB text file, then loops through and returns unique words with count of its occurrences in text file. Instead of using Thread Sleep or HttpClient to demonstrate async await, I have word count kind of example.

Create time taking library “WordCountLib”

  • Create blank solution naming “AsyncAwaitDemoApp”.
  • Create class library naming “WordCountLib” and create C# class file “WordCountClass”.
  • Copy below code containing methods “FindWordCounts” and “FindWordCountsAsync”.

  • Create C# class “Words”. This is POCO class to hold words name and its occurrences. Copy below

  • LongFile.txt contains text copied from http://norvig.com/big.txt ; I have copied all text twice so that file is 12MB and processing should take time. Ensure that you have file at D:\LongFile.txt or else FileNotFound exception. Its present in GitHub source now.

Building UI using WPF

  • Create WPF application “WordCount.UI”, add “WordCountLib” assembly reference so that we can call WordCountClass methods.
  • Open MainWindow.xaml and copy below code. This is startup window for our WPF. Draw using toolbar not so elegant but that’s  not needed.

Due to some issues in pasting XAML code, I have moved the entire demo application to GitHub, download it from Async Await Demo App

  • Open MainWindow.xaml.cs, its code behind file for our start up window. Copy the below code.
    • Method “btndwn_Click” is old school type of button click event handler for “Search Words”, it instantiate “WordCountClass”, calls “FindWordsCounts”, shows listbox and binds a list of words to listbox
    • Method “btndwnasyn_Click” is old school type of button click event handler for “Search Words Async Way”, it instantiate “WordCountClass”, calls “FindWordsCountsAsync”, shows listbox and binds a list of words to listbox. Note that it has async keyword in its method signature and await keyword while “FindWordsCountsAsync”
    • “Log” is very simple method to log information to screen.
  • Build and run it, check out image after it loads screen.

If we carefully see, await keyword is placed in-line while calling “FindWordsCountsAsync”. It clearly indicates this method is time-consuming and will block UI thread.

asyncAwaitWPF Window

WPF Main Window for Async Await Demo

Testing the responsiveness of the WPF UI

  • Click on button “Search Words”, try to move window, resize it. You can’t do anything as it reads the file, finds all words count and binds to list box. This is called non responsive UI or application hanging. Check out GIF image below. Notice that after it loads list box, screen window moves bit because after button click I tried to use window.
async NON responsive

Non Responsive UI on button click

  • Now run application again, click “Search Words Async Way”. Just move around window, resize it, see Log information being written. This called RESPONSIVE UI using Async Await in C#
  • Just play around it by clicking buttons back and forth.
responsive async await

Responsive UI using Async Await

 

  • Async methods are intended to be non-blocking operations. An await expression in an async method doesn’t block the current thread while the awaited task is running.
  • The async and await keywords don’t cause extra threads to be created. Async methods don’t need multi-threading because an async method doesn’t run on its own thread.

Leave a Reply