Updating the Windows Forms UI from async threads

There are many ways to update your UI from async ThreadPool threads. This is just one of them; my preferred way of doing so.

These are my general purpose methods, in my base form class, for updating the UI from methods that are running on ThreadPool threads. Before you jump up and down and accuse me of bad exemption handling here though, perhaps I should point out that I typically call these from long-running methods, where all I want is a way to safely update the user interface, and I do not care about exceptions there. I’m trapping all the important exceptions elsewhere, and I have global “handlers” that log unhandled exceptions. Any exceptions from these simple methods will thus:

  • If they are bugs, immediately be noticed by me in my log file. (Thus they never make it to the code of the released application.)
  • Otherwise, they will almost certainly indicate the application was going down already, and they should be ignored. (Those will normally in any case be of type InvalidOperationException or ObjectDsposedException, which are silently ignored.)

Again, the source, for this and a whole bunch of other stuff, is here: RomyView.zip

All the overloads do the same thing: Call Task.Factory.StartNew with a captured SynchronizationContext. (Technically, actually a TaskScheduler with a captured SynchronizationContext.)

The overloads allow me to call this with or without supporting cancellation, and with or without expecting a return value. Here is all the code, copied and pasted together so that it is easier to follow.

An example where I use this can be found in my post entitled Concurrent asynchronous processing of all the files in a directory with support for cooperative pausing, in C#

  1. private TaskScheduler uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
  3. [Browsable(false), CLSCompliant(false)]
  4. public TaskScheduler UiTaskScheduler
  5. {
  6.     get { return uiTaskScheduler; }
  7. }
  9. /// <summary>All the <b>InvokeOnUIthread</b> overloads exist to make it easier for code in async methods
  10. /// to return to the UI thread, with or without cancellation, and with or without a return value.</summary>
  11. /// <remarks>These methods wrap the boilerplate code that’s required to return to the UI thread, and are
  12. /// useful for code that runs in a threadpool thread and then updates a UI control. They don’t have to be
  13. /// used, since the <b>UiTaskScheduler</b> is inherited by all derived types as well.</remarks>
  14. public async Task InvokeOnUIthread(Action action)
  15. {
  16.     await InvokeOnUIthread(action, CancellationToken.None);
  17. }
  19. public async Task InvokeOnUIthread(Action action, CancellationToken ct)
  20. {
  21.     try
  22.     {
  23.         await Task.Factory.StartNew(() =>
  24.         {
  25.             action();
  26.         }, ct, TaskCreationOptions.PreferFairness, UiTaskScheduler);
  27.     }
  28.     catch (ObjectDisposedException) { }
  29.     catch (InvalidOperationException) { }
  30. }
  32. public async Task<T> InvokeOnUIthread<T>(Func<T> func)
  33. {
  34.     return await InvokeOnUIthread(func, CancellationToken.None);
  35. }
  37. public async Task<T> InvokeOnUIthread<T>(Func<T> func, CancellationToken ct)
  38. {
  39.     try
  40.     {
  41.         return await Task.Factory.StartNew(() =>
  42.         {
  43.             return func();
  44.         }, ct, TaskCreationOptions.PreferFairness, UiTaskScheduler);
  45.     }
  46.     catch (ObjectDisposedException) { }
  47.     catch (InvalidOperationException) { }
  49.     return default(T);
  50. }



About Jerome

I am a senior C# developer in Johannesburg, South Africa. I am also a recovering addict, who spent nearly eight years using methamphetamine. I write on my recovery blog about my lessons learned and sometimes give advice to others who have made similar mistakes, often from my viewpoint as an atheist, and I also write some C# programming articles on my programming blog.
This entry was posted in Programming and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s