在等待操作完成时显示进度条



在我的MVVMCross应用程序中,我有一个Android进度条定义为:

<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)" />

在 ViewModel 中,单击按钮启动操作时执行的代码如下所示:

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;
}

但是除非我删除最后一个IsBusy = false;,否则进度条不会显示,但这意味着仅在 Next() 方法退出时显示(而不是在等待时)

在等待时显示进度条并在导航到下一页之前禁用它,我可以做些什么?

===编辑====

结束这样做:

public void Next()
{
   async () =>
       {
           IsBusy = true;
           await DoWork();
           IsBusy = false;
       });
}

将其余代码添加到 DoWork 中

,等待任务
//THE EXPENSIVE OPERATION
var response = await CallTimeConsumingServiceReturningTask();
发生这种情况

是因为更新 UI 的过程当前与昂贵的操作发生在同一线程中。在操作完成之前,UI 线程将被阻止,并且视觉反馈永远不会正确显示。要解决此问题,您需要将CallTimeConsumingService()变成异步调用(使其返回Task<T>)并await以使其完成。

如果方法中有网络调用,则阻止方法具有已等待的异步对应项。如果您的方法只涉及繁重的处理,则应使用 TaskCompletionSourceTask.Run

前面的答案是正确的,但是您可以通过使next()方法异步来编写更干净的代码:

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;
}

最新更新