Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ensuring UI updates are on the UI thread

Tags:

c#

async-await

Consider:

async Task FooAsync()
{
    await BarAsync().ConfigureAwait(false);

    UpdateUI(); // Bug
}

I'm looking for a way to systematically ensure this doesn't happen.

Perhaps a naming convention, where methods that must be run on the UI thread get a special suffix. Or static checking, where an [UIThreadOnlyAttribute] on a method means that any caller must have that same attribute, and may not call ConfigureAwait(false).

Any suggestions?

like image 835
Jay Bazuzi Avatar asked Jan 12 '23 11:01

Jay Bazuzi


2 Answers

As long as your application is layered reasonably, it shouldn't be an issue.

UI layer (e.g., event handlers) and the logical UI layer (e.g., ViewModel) require a UI context and should not use ConfigureAwait. Other layers should use ConfigureAwait. That's a simple guideline that has worked well for me.

like image 96
Stephen Cleary Avatar answered Jan 28 '23 10:01

Stephen Cleary


As a sanity check, at the beginning of the UpdateUI method you can manually verify whether the current thread has the proper synchronization context. For a WinForms app, it could look like this:

void UpdateUI()
{
    Debug.Assert(SynchronizationContext.Current is WindowsFormsSynchronizationContext);
    // ... 
    // Do the actual UI update
}

For a WPF app, the first line would be:

Debug.Assert(SynchronizationContext.Current is DispatcherSynchronizationContext);

That works for me.

like image 29
noseratio Avatar answered Jan 28 '23 10:01

noseratio