Friday, December 22, 2017

Unloading the UI Thread in C# on Windows 10 + UWP

First I want to thank Matthew Groves for hosting the 1st known C# Advent (English).  I was honored to be able to grab the spot for Friday, December 22, 2017, which, happily, is the start of my Christmas holiday week, as well.

The crux of this post is that most visible performance issues in a Windows application come from the presentation layer.  Specifically, anything that puts load or wait states on the main "UI Thread" will make the app/application appear to hang or become unresponsive for periods of time. This post talks about strategies for getting load off the UI as much as possible, beyond the async/await mechanism in C#.  Most such load can be unloaded to a worker thread fairly easily.  Other tasks can be awaited together. In some cases, a UI component is involved, and it becomes necessary to manage load that, for that reason, reason MUST stay on the UI thread.

I remember when I was a kid hearing of projects for stock traders that handled hundreds of data update events every second and being totally intimidated by the thought of it.  I knew I'd "come of age" in technology when, in 2017, I worked with a focused team (known as "Blockheads") to build such an app.  This latest generation "stock blotter" ran stable, without memory leakage, and with no apparent lag at tens of Gigabytes per second! These general ideas stem back to the project I worked on in 2016-2017 with BlueMetal for Fidelity Investments' Equity Trading team, called Artis OMT.  Artis OMT has been on Fidelity's Equity Trading floor for over a year now, and will soon reach a year of full deployment.  While Artis OMT was WPF, this post looks at similar performance ideas in a similar but different platform:  Windows 10 UWP (store apps).

Artis OMT didn't start out able to handle 90Gigabytes of incoming data.  We had to use JetBrains tools to identify code that was bogging down or hanging the main UI thread.   That analysis, alone, is perhaps the subject of a different post, or more, some day.

When folks start thinking about UI Thread execution, the first thing most think of is Dispatcher.BeginInvoke().  This method is how you add workload to the UI thread.  I'm trying to talk about how to UNLOAD the UI thread, and/or manage your load so that the user won't observe UI freezes or lockups.


Here, however, are a few relatively easy ways to really make use of the extra cores in your CPU, and make your apps appear to perform much better:

Task.Run(() => { ... });
Classic depiction of processes running in sequence vs in parallel

The title of this says it all, really.  Push a workload off the current thread.  Use whenever you have long running processes that you don't have to touch UI controls from.   If you have timing dependencies, you can manage them with Task.When, Task,Wait, or even better, Task.ContinueWith().  Examples below cover this a little more.



Batch remote service calls using Tasks and WhenAll()

Service calls are low hanging fruit.  So often I see code that makes calls in series, waiting on the results of one before making the next call, even though the two calls have no dependencies on each other...  it's just so much easier to write the sequence case that folks let it hang.   await Task.WhenAll(...) is not as syntactically sweet, but still MUCH sweeter than having to set up an aggregate event.



///

/// Does one request at a time, holding up the entire process
/// at each step until it completes. Simpler code but....
/// Total time spent is the sum of all tasks' time.
///
public async void GetContentinSequence(Session session)
{
    var dbContent = await GetDatabaseContent(session);
    var webContent = await GetWebContent(session);
    var userProfile = await GetUserProfile(session);
    var userContext = await GetUserContext(session);
}



///

/// Executes all requests simultaneously, letting the default task dispatcher do its thing.
/// total time spent is no more than the longest running individual task, all other things being equal.
///
public async void GetContentinParallel(Session session)
{
    var contextTask = GetDatabaseContent(session);
    var webContentTask = GetWebContent(session);
    var userProfileTask = GetUserProfile(session);
    var userContextTask = GetUserProfile(session);

    var stuff = new Task[] { contextTask, webContentTask, userProfileTask, userContextTask };
    await Task.WhenAll(stuff);

    var dbContent = contextTask.Result;
    var webContent = webContentTask.Result;
    var userProfile = userProfileTask.Result;
    var userContext = userContextTask.Result;
}

Here's an example that makes this more clear:


var start = DateTimeOffset.Now;
var task1 = Task.Run(async () => { await Task.Delay(1000); });
var task2 = Task.Run(async () => { await Task.Delay(1500); }); //1.5 seconds
var task3 = Task.Run(async () => { await Task.Delay(1000); });
var task4 = Task.Run(async () => { await Task.Delay(1000); });
var tasks = new Task[] { task1, task2, task3, task4 };
Task.WhenAll(tasks).ContinueWith(t => { Debug.WriteLine(DateTimeOffset.Now - start); });


outputs something like:
00:00:01.5623681

As always, there's some overhead with task switching.  You'll notice that the time was just a few ticks longer than 1.5 seconds.

What if you can't unload the UI thread?  what if your long running process must interact with controls like a huge grid that needs to calculate an aggregation of a data set that lives in it?   

Here's an option...

DoEvents() erhhh... ummm...  await Task.Delay(...)

I once scrubbed references to Visual Basic from my CV and landed a job that had scrubbed VB from the job description.  I didn't want to work for a company that would hire a "VB-Weenie" and they didn't want to hire a "VB-Weenie", either... but there was VB6 work to do. 

One thing that VB6 had going for it was a concept called DoEvents().   It enabled you to give up processing the current method to allow any pending events to execute. It would then return to finish the calling method.

In C#, the closest equivalent, nowadays, is "await Task.Yield()" or await.Task.Delay(...).

Most folks talk about using "await Task.Yield()" at the start of an awaitable method to make sure the whole method runs asynchronously.  There's some sense to that.   More importantly, one can interrupt long running processes that must run on the UI in order to allow the UI to respond to user inputs.  In testing, I've seen that Task.Yield() often doesn't allow enough room for redraws of the UI.  Likewise, setting a Task.Delay of a 1 tick timespan isn't enough, either.  1 millisecond delay, however, does seem to suffice in my basic testing.

private async void LongRunningAggregatorOnUIThread(object sender, object e)

{
    await Task.Yield();
    timer.Stop();
    var timeoutRate = TimeSpan.FromMilliseconds(100);

    
    var timeout = DateTimeOffset.Now.Add(timeoutRate);
    var value = 0L;
    while (true)
    {
        value++;
        if (DateTimeOffset.Now >= timeout)
        {
            textbox.Text = value.ToString();
            await Task.Delay(1);
            timeout = DateTimeOffset.Now.Add(timeoutRate);
        }
    };
}


As always, use this very carefully.  This has overhead of its own, as well, that can cause performance issues.... including potential deadlocks.

41 comments:

anushya said...

the above content you shared is very useful and the way of presentation is easy to understand.
Selenium Training in Bangalore
Selenium Course in Bangalore
AWS Training in Bangalore
Devops Training in Bangalore
Java Training in Bangalore
Data Analytics Training in Bangalore
Digital Marketing Training in Bangalore
Python Course in Bangalore

velraj said...

I am feeling happy to read this. You gave nice info to me. Please update more.
Ethical Hacking course in Chennai
Ethical Hacking Training in Chennai
Hacking course in Chennai
ccna course in Chennai
Salesforce Training in Chennai
AngularJS Training in Chennai
PHP Training in Chennai
Ethical Hacking course in Tambaram
Ethical Hacking course in Velachery
Ethical Hacking course in T Nagar

Aparna said...

I would like to thank you so much for sharing with us and I have many ideas after visiting your post. Well done...
JMeter Training in Chennai
JMeter Certification
Linux Training in Chennai
Pega Training in Chennai
Primavera Training in Chennai
Unix Training in Chennai
Placement in Chennai
Tableau Training in Chennai
Oracle Training in Chennai
JMeter Training in T Nagar
JMeter Training in OMR

Adhuntt said...

Great blog thanks for sharing Looking for the best creative agency to fuel new brand ideas? Adhuntt Media is not just a digital marketing company in chennai. We specialize in revamping your brand identity to drive in best traffic that converts.

Karuna said...

Nice blog thanks for sharing Is this a special day for you? Beautiful and fragrant flowers are sure to make it even more amazing of a day no doubt. This is why Karuna Nursery Gardens offers you the best rental plants in Chennai that too at drop dead prices.

Pixies said...

Excellent blog thanks for sharing Pixies Beauty Shop is unlike any of the other cosmetic shops in Chennai. With tons of exclusive imported brands to choose from and the best value, this is the best shopping destination for your personal and salon needs.

Unknown said...

Awesome blog thanks for sharing While choosing your perfect ride for driving, Accord Cars comes with and the best packages for you to pick from. Self drive Cars in Chennai are done the easier. Just pick out your plan from hourly, daily, weekly and even monthly plans available.

Unknown said...

Very useful blog thanks for sharing At Pearl’s - The best Bridal Makeup Parlour in Chennai, we take personal responsibility in making sure that you look as flawless and beautiful and the marriage that you have been dreaming of. With around 16,000 successful brides in our books, you can be confident that we know our art intimately and deep.

Durai Moorthy said...

Thank you for sharing such a piece of great information very useful to us
AWS Training in Bangalore
RPA Training in Kalyan Nagar
Data Science with Python Training Bangalore
AWS Training in Kalyan Nagar
RPA training in bellandur
AWS Training in bellandur
Marathahalli AWS Training Institues
Kalyan nagar AWS training in institutes
Data Science Training in bellandur
Data Science Training in Kalyan Nagar

jagedheesh kumar said...

Very good information provided, Thanks a lot for sharing such useful information.
salesforce Training in Bangalore
uipath Training in Bangalore
blueprism Training in Bangalore

nisha raj said...

Your post is just outstanding! thanx for such a post,its really going great and great work.
python training in kalyan nagar|python training in marathahalli
selenium training in marathahalli|selenium training in bangalore
devops training in kalyan nagar|devops training in bellandur
phthon training in bangalore

Archana said...

Good post!Thank you so much for sharing this lovely article.It was so good to read and useful to upgrade my understanding...
salesforce Training in Bangalore
uipath Training in Bangalore
blueprism Training in Bangalore

Deepthi said...

Wonderful Blog!!! Your post is very informative about the latest technology. Thank you for sharing the article with us
aws Training in Bangalore
python Training in Bangalore
hadoop Training in Bangalore
angular js Training in Bangalore
bigdata analytics Training in Bangalore

Bhanu Ravi said...

A very nice post. Thanks for sharing such a piece of valuable information...
aws Training in Bangalore
python Training in Bangalore
hadoop Training in Bangalore
angular js Training in Bangalore
bigdata analytics Training in Bangalore

norhan said...


تعد الاول افضل شركة غسيل خزانات بالمدينة المنورة تعمل على استخدام افضل ادوات تنظيف وتعقيم خزانات المياه

ethiraj raj said...

Thanks for sharing an informative article. keep update like this...
aws Training in Bangalore
python Training in Bangalore
hadoop Training in Bangalore
angular js Training in Bangalore
bigdata analytics Training in Bangalore

Extensiya said...

Awesome blog thankks for sharing 100% virgin Remy Hair Extension in USA, importing from India. Premium and original human hair without joints and bondings. Available in Wigs, Frontal, Wavy, Closure, Bundle, Curly, straight and customized color hairstyles Extensions.

Indpac said...

Very useful blog thanks for sharing IndPac India the German technology Packaging and sealing machines in India is the leading manufacturer and exporter of Packing Machines in India.

bill.wood said...

I learned that any attempt to make Internet teaching like classroom teaching was a farce. Lectures on the Internet, meant to simulate classroom lectures, are a calamity and the real-time nature of the attempt is a technological nightmare. Teaching via the Internet it is best done asynchronously. machine learning training in hyderabad

sudhan said...

Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging.
Cyber Security Training Course in Chennai | Certification | Cyber Security Online Training Course | Ethical Hacking Training Course in Chennai | Certification | Ethical Hacking Online Training Course | CCNA Training Course in Chennai | Certification | CCNA Online Training Course | RPA Robotic Process Automation Training Course in Chennai | Certification | RPA Training Course Chennai | SEO Training in Chennai | Certification | SEO Online Training Course

Data Science Training in Bangalore said...

I am delighted to discover this page. I must thank you for the time you devoted to this particularly fantastic reading !! I really liked each part very much and also bookmarked you to see new information on your site.

Business Analytics Course in Bangalore

Data Analytics Course said...

It took me a while to read all the reviews, but I really enjoyed the article. This has proven to be very helpful to me and I'm sure all the reviewers here! It's always nice to be able to not only be informed, but also have fun!

Data Analytics Course in Bangalore

Tableau Course said...

It took a while to understand all the comments, but I really enjoyed the article. It turned out to be really helpful for me and I'm positive for all the reviewers here! It's always nice to be able to not only be informed, but also entertained! I'm sure you enjoyed writing this article. Tableau Course in Bangalore

Data Science Training said...

Really nice and interesting blog information shared was valuable and enjoyed reading this one. Keep posting. Thanks for sharing.
Data Science Training in Hyderabad

Emerging Technology said...

Fantastic blog with high quality content found very valuable and enjoyed reading thank you.
Data Science Course

360digiTMG Training said...

I don t have the time at the moment to fully read your site but I have bookmarked it and also add your RSS feeds. I will be back in a day or two. thanks for a great site.
Digital Marketing Courses in Hyderabad With Placements

Banumadhu said...

Excellent blog thanks for sharing the valuable information..it becomes easy to read and easily understand the information.
Useful article which was very helpful. also interesting and contains good information.
to know about python training course , use the below link.

Python Training in chennai

Python Course in chennai




Maneesha said...

You really make it look so natural with your exhibition yet I discover this issue to be really something which I figure I could never understand. It appears to be excessively confounded and incredibly wide for me. I'm searching forward for your next post, I'll attempt to get its hang! data scientist training

DataScience Specialist said...

I have to search sites with relevant information ,This is a
wonderful blog,These type of blog keeps the users interest in
the website, i am impressed. thank you.
Data Science Course in Bangalore

technology said...

There are two clear ways of selecting employees to be part of your trial group, Salesforce interview questions

360DigiTMGNoida said...

This post is very simple to read and appreciate without leaving any details out. Great work!
data science courses in noida

360DigiTMG said...

nice blog!! i hope you will share a blog on Data Science.
data science course

360DigiTMG_Gurgaon said...

Nice article. I liked very much. All the information given by you are really helpful for my research. keep on posting your views.
data science course in gurgaon

data scientist course said...

This post is extremely easy to peruse and acknowledge without forgetting about any subtleties. Incredible work!
data scientist training and placement

Srigokul said...

Useful information, Thank you for sharing...

Data science training in chennai
Data science course in chennai

360digiTMG Training said...


Impressive. Your story always brings hope and new energy. Keep up the good work.

business analytics course

360digiTMG Training said...


Very awesome!!! When I searched for this I found this website at the top of all blogs in search engines.

Data Science Training in Hyderabad

Aishwariya said...

After reading your article I was amazed. I know that you explain it very well. And I hope that other readers will also experience how I feel after reading your article. Primavera Course in Chennai | Primavera online course

Pallavi reddy said...

i am glad to discover this page : i have to thank you for the time i spent on this especially great reading !! i really liked each part and also bookmarked you for new information on your site.
data science courses in hyderabad

Deekshitha said...

Informative blog
data scientist course in Bangalore

Datascience Books said...

Excellent Blog! I would like to thank for the efforts you have made in writing this post. I am hoping the same best work from you in the future as well. I wanted to thank you for this websites! Thanks for sharing. Great websites!
Data Science Training in Bangalore