0

im developing a medium sized WPF application, i already got the first screen mostly working, but i am wondering about UI locking.

Right now, when opening a tab my UI doesnt lock since i use code like this for loading data from the DB at the start.

await Task.Run(() => dbService.loadData());

However i noticed that its sometimes locking when i calculate something that takes even a slight amount of time. Or if i run an update command to my database.

Do i just need to wrap pretty much everything in this strange async Task construct? That can't be right.

This gets especially annoying since i put a IsLoading boolean around it, which is bound to an indicator and disables the UI. Disable/enable the UI for a whole .3 seconds makes for a really user unfriendly flickering effect. So i came up with this construct around my update command.

var t = new Timer(500);
t.Elapsed += (s,e) () => IsLoading = true; 
t.Start();

await Task.Run(() => dbService.UpdateData());
t.Stop();
IsLoading = false;

I feel like i didnt describe my problem very well, but this code is it.

There have to be smarter/shorter ways to solve UI locking. I cant be forced to do all of this every time just to call one line. Even with extracting it into a helper method it seems silly.

DFENS
  • 289
  • 1
  • 12
  • A "smarter" way than avoiding blocking the UI thread with so much work that it can't handle the input? I don't think so. A single thread cannot both respond to user input and execute your code simultaneously. This is impossible. – mm8 Sep 13 '19 at 13:02
  • This answer may be USEFUL https://stackoverflow.com/questions/4253088/updating-gui-wpf-using-a-different-thread – yu yang Jian Jun 25 '20 at 13:38

1 Answers1

1

If you are performing processing that will tie up the UI thread for noticeable periods, then yes, you need to farm off the task to another thread, or chop it up into smaller chunks that won't be noticed (which async / await is good at).

You don't have to wrap every task in Task.Run(), although that is one way. You could have a single background worker thread that does all the "processing" type tasks and just posts to the UI with updates instead. Or you could use async DB calls if such things exist (never done async DB work).

As for your disabling UI flicker, you need to decide whether your UI should be disabled or not. Either it always needs to be disabled to ensure the user cannot edit during transition states, or if edits are not a problem, then never disable the UI, and optionally add a busy spinner or just disable certain buttons to denote work being done. Currently you have a strange hybrid situation where things can be edited for half a second.

GazTheDestroyer
  • 20,722
  • 9
  • 70
  • 103