Reputation: 4822
In my MVVMCross App I have an Android ProgressBar defined as:
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:progressDrawable="@drawable/circular_progress_bar"
android:gravity="right"
local:MvxBind="Visibility Visibility(IsBusy)" />
In the ViewModel, the code executed when clicking the button to start the operation is like:
public void Next()
{
IsBusy = true;
try
{
//THE EXPENSIVE OPERATION
var response = CallTimeConsumingService();
if (response.MethodFailed)
{
_dialogService.DisplayAlert(this, response.Message);
return;
}
ShowViewModel<ShowNextView>();
}
catch (Exception ex)
{
_dialogService.DisplayAlert(this, ex.Message);
}
IsBusy = false;
}
But the ProgressBar is not displayed unless I remove the last IsBusy = false;
,
but that means is just displayed when the Next() method hass exited (not while waiting)
What can I do to display the ProgressBar while waiting and disable it before navigating to the next page?
===EDIT====
Ended doing this:
public void Next()
{
async () =>
{
IsBusy = true;
await DoWork();
IsBusy = false;
});
}
adding the rest of the code to the DoWork with an await for the task
//THE EXPENSIVE OPERATION
var response = await CallTimeConsumingServiceReturningTask();
Upvotes: 0
Views: 821
Reputation: 6375
Previous answer is correct, but you can write a cleaner code by making the next() method async:
public async Task Next()
{
IsBusy = true;
try
{
//THE EXPENSIVE OPERATION
var response = await CallTimeConsumingServiceReturningTask();
if (response.MethodFailed)
{
_dialogService.DisplayAlert(this, response.Message);
return;
}
ShowViewModel<ShowNextView>();
}
catch (Exception ex)
{
_dialogService.DisplayAlert(this, ex.Message);
}
IsBusy = false;
}
Upvotes: 1
Reputation: 5005
This is happening because the process of updating the UI is currently happening in the same thread as your expensive operation. Until your operation is completed, the UI thread is blocked and the visual feedback is never shown properly. To solve this, you need to make your CallTimeConsumingService()
into an async call (making it return a Task<T>
) and await
for it to complete.
If you have network calls in your method, the blocking methods have Async counterparts that are awaitable already. If your method just involves heavy processing, you should use TaskCompletionSource
or Task.Run
.
Upvotes: 2