Xamarin Tabbed Forms App Template: Spinner Does Not Stop, Async Task Void

BretBret USMember ✭✭
edited December 2019 in Xamarin.Forms

I'm running a template right out-of-the-box on a Mac. To test yourself, you can simply go to Visual Studio:

  1. File
  2. New Solution
  3. Multiplatform: App
  4. Tabbed Forms App

When running this on an iPhone device or iPhone emulator, the spinner at the top of the list will not stop spinning. I suspect it is due to this code in the shared forms project:

public class ItemsViewModel : BaseViewModel
    {
        public ObservableCollection<Item> Items { get; set; }
        public Command LoadItemsCommand { get; set; }

        public ItemsViewModel()
        {
            Title = "Browse";
            Items = new ObservableCollection<Item>();
            LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());

            MessagingCenter.Subscribe<NewItemPage, Item>(this, "AddItem", async (obj, item) =>
            {
                var newItem = item as Item;
                Items.Add(newItem);
                await DataStore.AddItemAsync(newItem);
            });
        }

        async Task ExecuteLoadItemsCommand()
        {
            if (IsBusy)
                return;

            IsBusy = true;

            try
            {
                Items.Clear();
                var items = await DataStore.GetItemsAsync(true);
                foreach (var item in items)
                {
                    Items.Add(item);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
            finally
            {
                IsBusy = false;
            }
        }
    }

Specifically, the fact that LoadItemsCommand = new Command(async () => await ExecuteLoadItemCommand()), which, along with the method signature, is treating this like an async Task.

I though invoking Tasks as void was a big no-no because, among other reasons, the CLR state machine can't do anything with the result(s) of the task? Additionally, anything that this task changes that is being watched by some delegate, notable IsBusy, will not be impacted?

From BaseViewModel.cs:

public class BaseViewModel : INotifyPropertyChanged
{
    public IDataStore<Item> DataStore => DependencyService.Get<IDataStore<Item>>();

    bool isBusy = false;
    public bool IsBusy
    {
        get { return isBusy; }
        set { SetProperty(ref isBusy, value); }
    }
 ...
}

From the view, specifically the spinner control, ItemsPage.xaml:

IsRefreshing="{Binding IsBusy, Mode=OneWay}"

Tagged:

Best Answer

  • BretBret US ✭✭
    Accepted Answer

    After updating the following within the Forms and iOS projects,

    • Xamarin.Forms (4.2.0.709249) -> (4.4.0.991265)
    • Xamarin.Essentials (1.2.0) -> (1.3.1)

    the spinner now stops spinning once the list is loaded. It should be noted that when these projects are being created, despite Visual Studio being up-to-date, it is choosing to create said projects with dated NuGet packages. I'm not sure if that is expected behavior.

Answers

  • LucasZhangLucasZhang Member, Xamarin Team Xamurai
    edited December 2019

    I tested your code with static data and it works fine on my side .

     LoadItemsCommand = new Command(async () => {
    
         IsBusy = true;
    
         try
         {
            await Task.Delay(5000);
         }
         catch (Exception ex)
         {
    
         }
    
         finally
         {
              IsBusy = false;
          }
    
    });
    

    Maybe your issue caused by the code which get data from DataBase . You can try my code firstly to check if the issue still exists .

  • BretBret USMember ✭✭

    I am not using a database. I am using static data. I have changed nothing in the template project that can be created by reproducing the steps that I provided above. Thanks.

    @LucasZhang said:
    I tested your code with static data and it works fine on my side .

     LoadItemsCommand = new Command(async () => {
    
         IsBusy = true;
    
         try
         {
            await Task.Delay(5000);
         }
         catch (Exception ex)
         {
    
         }
    
         finally
         {
              IsBusy = false;
          }
    
    });
    

    Maybe your issue caused by the code which get data from DataBase . You can try my code firstly to check if the issue still exists .

  • BretBret USMember ✭✭

    UPDATE: This does not occur on an Android device or Android emulator; this is an iOS device and iOS emulator specific bug.

  • BretBret USMember ✭✭
    Accepted Answer

    After updating the following within the Forms and iOS projects,

    • Xamarin.Forms (4.2.0.709249) -> (4.4.0.991265)
    • Xamarin.Essentials (1.2.0) -> (1.3.1)

    the spinner now stops spinning once the list is loaded. It should be noted that when these projects are being created, despite Visual Studio being up-to-date, it is choosing to create said projects with dated NuGet packages. I'm not sure if that is expected behavior.

Sign In or Register to comment.