Yes, this is a very common scenario that the designers of WPF did a bad job providing for.
e.g.
StatusbarText = "Saving ...";
await SaveOperation();
StatusbarText = "Save complete";
In the above code the user won't see "Saving ..." appear on screen.
StatusbarText = "Saving ...";
await SaveOperation();
StatusbarText = "Save complete";
Unfortunately WPF does not provide access to the rendering thread
(or they've hidden it away somewhere)
So you're stuck with having to wait on the main UI thread instead.
I've seen various post with Dispatcher.Invoke or Dispatcher.BeginInvoke but they didn't work for
me, or worked intermittently.
Others suggest re-writing everything to use background threads
(for something that should not need a background thread)
What worked for me was using a DispatcherTimer and Dispatcher.Yield()
If you put a breakpoint on the await SaveOperation() line you can see that the text has been updated
StatusbarText = "Saving ...";
await UIFinishRender();
await SaveOperation();
StatusbarText = "Save complete";
public async Task UIFinishRender()
{
RenderCount = 0;
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(1);
timer.Tick += timer_Tick;
timer.Start();
while (RenderCount < 30)
{
await Dispatcher.Yield();
}
}
void timer_Tick(object sender, EventArgs e)
{
RenderCount++;
}