UI 调用异步方法后进度条才会更新

UI Progress bar not updating until after async method is called

我试图在加载服务时显示一个简单的进度条。我终其一生都无法弄清楚为什么这不会立即执行。

查看:

<ProgressBar x:Name="ProgressBar" 
    IsIndeterminate="True" 
    Visibility="{Binding IsLoading, Mode=OneWay, Converter={StaticResource BoolToVisiblityConverter}}"   />

查看模型:

private Boolean _isLoading;
public Boolean IsLoading
    {
        get { return _isLoading; }
        set
        {
            Set(ref _isLoading, value);
        }
    }

public SignInViewModel(INavigationService navigationService)
    {
        IsLoading = false;
        _navigationService = navigationService;
        Username = "";
        SignInCommand = new RelayCommand( SignIn, CanSignIn);
    }

private async void SignIn()
    {

  //    DispatcherHelper.CheckBeginInvokeOnUI(() =>
  //       {
               IsLoading = true;
               RaisePropertyChanged("IsLoading");
   //      });

        var response = await OrchestratorContext.Instance.SignInWithPassword(_username, _password);

        if (response.IsSuccessful)
        {
            //     _navigationService.NavigateTo("LandingPage");
        }
    }

进度条在登录功能完成后才会开始加载。我试过使用调度程序,还尝试在设置后提升 属性 更改。有什么建议吗?

我不确定这是否是最好的方法,但我通过强制一个新线程让它工作。有没有更好的方法?

private void SignIn()
    {
        IsLoading = true;

        Task.Factory.StartNew(async () =>
        {
            var response = await OrchestratorContext.Instance.SignInWithPassword(_username, _password);

            if (response.IsSuccessful)
            {
                DispatcherHelper.CheckBeginInvokeOnUI(() =>
                    {
                        _navigationService.NavigateTo("LandingPage");
                    });
            }
        });
    }

你正确地注意了,如果你想在你的函数中的某个地方使用 await,这个函数应该被声明为异步。

但是,每个异步函数都应该 return Task(如果它通常会 return void)或 Task<TResult> 如果它通常会 return TResult。

有一个例外:事件处理程序可以 return void 而不是 Task,但是,事件处理程序仍然必须声明为异步。

如果您遵循这些规则,您的 UI 将保持响应并且进度条会不断更新:

private async void Button1_clicked(object sender, ...)
{
    await Signin();
}

private async Task SignIn()
{
    // do some processing
    var response = await OrchestratorContext...
    // do some more processing
}

注意 Signin() 的任务 return 值

现在在等待期间 UI 保持响应。