Xamarin.forms等待指示符未在正常等待函数上显示

时间:2019-01-21 19:55:20

标签: xamarin.forms

我需要一些信息。单击登录按钮后,我得到了一个登录功能。在异步函数的开始,我设置IsBusy = true,然后调用等待的LoginAsynx(user,pass)函数。 加载指示灯不弹出。所以我尝试添加一个等待Task.Delay(100);在IsBusy = true之后,在登录功能之前,现在正在加载动画。

我是xamarin.form的新手,所以我不明白为什么会发生这种现象。就像await函数来快速完成并在IsBusy = true完成绑定之前锁定UI线程一样。

编辑1 命令调用功能:

public ICommand SignInCommand => new Command(async () => await SignInAsync());

这里是我的LoginViewModel

    private async Task SignInAsync()
    {
        IsBusy = true;
        await Task.Delay(100);   // If I remove that, no more wating indicator
        bool isValid = Validate();

        if (isValid)
        {

            try
            {
                KelvinLoginResult LoginResult = await _kelvinService.LoginAsync(UserName.Value, Password.Value);
                if (LoginResult.EstAuthtifie == false)
                {
                    await DialogService.ShowAlertAsync("Authentication error", "Authentication error", "Ok");
                }
                else
                {
                    await NavigationService.NavigateToAsync<MainViewModel>();
                    //await NavigationService.RemoveLastFromBackStackAsync();
                }
            }
            catch (Exception ex)
            {

                await DialogService.ShowAlertAsync(ex.Message, "Error", "Ok");
            }            
        }

        IsBusy = false;
    }

编辑2: 表单上的活动指示器

    <!-- INDICATOR -->
    <ActivityIndicator      
      Color="{StaticResource LightGreenColor}"
      IsRunning="{Binding IsBusy}"
      IsVisible="{Binding IsBusy}"
      VerticalOptions="Center"
      HorizontalOptions="Center">
        <ActivityIndicator.WidthRequest>
            <OnPlatform x:TypeArguments="x:Double">
                <On Platform="iOS, Android" Value="100" />
                <On Platform="UWP, WinRT, WinPhone" Value="400" />
            </OnPlatform>
        </ActivityIndicator.WidthRequest>
    </ActivityIndicator>

编辑3

    public bool IsBusy
    {
        get
        {
            return _isBusy;
        }

        set
        {
            _isBusy = value;
            RaisePropertyChanged(() => IsBusy);
        }
    }

3 个答案:

答案 0 :(得分:0)

设置IsBusy属性值必须在主线程中完成,异步方法可能会在主线程上调用,也可能不会调用,这不是抢先的。

所以我的建议是:

  • 在调用登录方法之前,将IsBusy设置为true属性。
  • 在将IsBusy属性设置为false时使用Device.BeginInvokeOnMainThread方法,这将确保它在主线程中运行。

此外,如果您的登录方法太快并且不会花费足够长的时间来显示等待指示符,那么,您可以考虑创建一个延迟任务以确保将显示等待指示符。您可以编写类似以下内容的代码:

IsBusy = true;
var delayTask = Task.Delay(100);
var loginTask = Login();
await Task.WhenAll(delay, login);
IsBusy = false;

答案 1 :(得分:0)

好的,所以在所有这些更新之后...这应该是答案-您需要使用Task.Run来运行SigninAsync方法。

答案 2 :(得分:0)

  

在异步函数的开始,我设置IsBusy = true,然后调用等待的LoginAsynx(user,pass)函数。加载指示灯不弹出。所以我尝试添加一个等待Task.Delay(100);在IsBusy = true之后,在登录功能之前,现在正在加载动画。

这种行为告诉我这段代码:

  

KelvinLoginResult LoginResult =等待_kelvinService.LoginAsync(UserName.Value,Password.Value);

实际上不是异步的。几乎可以肯定是同步的。

正确的解决方案是使LoginAsync异步,例如在该方法中使用asyncawait