In both .NET and in Android and I’m sure other frameworks I’ve noticed this issue where you end up with a task that takes too long and so holds up the UI thread.
Say you have a method that updates a label with text from a network location/internet and comes back again after 3-4 seconds and sets the label appropriately. That holds up the UI thread.
So your first port of call then is to move the method call to a different thread.
Only that doesn’t just work… because you can no longer update the text of label since that can only be done in the UI thread….
So then the language provides something along the lines of
runOnUiThread(() -> {
label.setText(myNewFoundInformationFrom);
});
That example is from Android using lambda’s and is no doubt a massive improvement on what we might have used 10 years ago…
Maybe further down the line you find yourself doing this from various different places… so you might create a method
void setLabelText(string newText)
runOnUiThread(() -> {
label.setText(newText);
});
and at least in the case of Android… this works no matter which thread I run it from.
So this makes me wonder… Why don’t Microsoft/Google and all make it so that all update methods/functions to UI controls already make sure that they’re running from the UI thread in this way – so that we don’t have to?
0
There are some concerns that may prevent such an always-runInUiThread approach.
The primary problem is that if you’re in a non-UI thread, your operations are deferred by being posted onto a queue, so you have no idea of when your actions will actually take effect. If you have several changes that need to take effect at the same time, you need to group them in a lambda/function anyway and post it as usual, as otherwise another thread may manage to slip in a posted task between your tasks.
This has an analogue in resource synchronization, where it’s incredibly common that you need to perform several operations under the same lock.
Synchronous functions are important, as you sometimes need to know that the result is locked in before continuing.
When you want to change just one label, there is not problem with the solution you have suggested. There are, however, at least two scenarios, in what this makes sense:
- Synchronization. Say, you want to update a button text and enable/disable it. With runOnUiThread, there is no need for explicit synchronization or locking.
- Bulk update. If you are updating many items, then calling runOnUiThread for every one item would hurt the performance. (Well, if there is horrible amount of items, you should divide them in several batches.)
1