I am having difficulty updating the UI using Xamarin. The objective is to make reactive UI so the user knows that application is thinking. Below are my attempts.
Attempt 1
private void BeginProcess(string fileName)
{
Device.BeginInvokeOnMainThread(() => {
iContent.Text = "UI Successfully updated.";
});
Device.BeginInvokeOnMainThread(() => {
ProccessFolder testMethod = new ProccessFolder.Initialize(fileName);
});
}
Attempt 2
private void UpdateUI () {
iContent.Text = "UI Successfully updated.";
}
private void BeginProcess(string fileName)
{
System.Threading.Thread t = new System.Threading.Thread(UpdateUI);
t.Priority = System.Threading.ThreadPriority.Highest;
t.IsBackground = false;
t.Start();
Device.BeginInvokeOnMainThread(() => {
ProccessFolder testMethod = new ProccessFolder.Initialize(fileName);
});
}
Attempt 3
private void BeginProcess(string fileName)
{
Device.BeginInvokeOnMainThread(() => {
iContent.Text = "UI Successfully updated.";
});
Task.Delay(5000);
Device.BeginInvokeOnMainThread(() => {
ProccessFolder testMethod = new ProccessFolder.Initialize(fileName);
});
}
Unfortunately none of these work. What does work is if I place the ProcessFolder method in a background thread and invoke the UI changes on the main thread. However the completion time of the ProcessFolder method is slower.
Any suggestion on how I can update the UI while still executing ProcessFolder on the main thread?
Sometimes when your try update something on the main ui from within a method, depending on the way you've written (and/or structured) it can mean that the main dispatcher waits for the method to complete before updating the main ui.
If you were to try the following example it would successfully complete a UI update after each foreach iteration because when it completes it's initial task it wants to return out of the for loop and hits our main thread invoke, which HAS to complete before the loop can iterate again.
private void BeginProcess()
{
Task.Run(()=>{
for (int i = 0; i < 100; i++)
{
// Perform a task
BeginInvokeOnMainThread(() => {
iContent.Text = "UI Successfully updated: " + i " times out of 100";
});
}
})
}
You can sometimes replicate this kind of effect by using:
NSRunLoop.Current.RunUntil(1000);
to allow the UI to catch up when you call the 'BeginInvokeOnMainThread' delegate.
First of all, all the UI updates must be done in the main thread.
For your particular problem maybe you could use async/await (https://msdn.microsoft.com/library/hh191443(vs.110).aspx)
You could do something like in the main thread:
ProccessFolder testMethod = await ProccessFolder.Initialize(fileName);
iContent.Text = "UI Successfully updated.";
You have to make the Initialize method async and to return a task
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With