代码之家  ›  专栏  ›  技术社区  ›  Pierre-D Savard

xamarin.forms等待指示灯不显示在正常等待功能上

  •  0
  • Pierre-D Savard  · 技术社区  · 6 年前

    我需要一些信息。单击登录按钮后,调用了一个登录函数。在异步函数的开头,我将isbusy设置为true,然后调用await loginasynx(user,pass)函数。 加载指示灯不弹出。因此,我尝试添加一个wait task.delay(100);刚好在isbusy=true之后,登录函数之前,现在加载动画工作。

    我刚接触过xamarin.form,所以我不明白为什么会发生这种行为。就像在isbusy=true完成绑定之前,await函数快速启动并锁定UI线程一样。

    编辑1 调用函数的命令:

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

    这里是我的LoginView模型

        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 回复  |  直到 6 年前
        1
  •  0
  •   Stephen Cleary    6 年前

    在异步函数的开头,我将isbusy设置为true,然后调用await loginasynx(user,pass)函数。加载指示灯不弹出。因此,我尝试添加一个wait task.delay(100);刚好在isbusy=true之后,登录函数之前,现在加载动画工作。

    这个行为告诉我这个代码:

    kelvinloginresult loginresult=等待kelvinservice.loginasync(username.value,password.value);

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

    正确的解决办法是 LoginAsync 异步,例如,使用 async await 在这种方法中。

        2
  •  0
  •   Elton Santana    6 年前

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

    所以我的建议是:

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

    另外,如果您的登录方法太快,并且显示等待指示器的时间不够长,那么您可以考虑创建延迟任务,以确保显示等待指示器。您可以编写如下代码:

    IsBusy = true;
    var delayTask = Task.Delay(100);
    var loginTask = Login();
    await Task.WhenAll(delay, login);
    IsBusy = false;
    
        3
  •  0
  •   Ivan Ičin    6 年前

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