1

My PlayerService class:

public static class PlayerService
    { 
        private static SQLiteAsyncConnection db;

        /// <summary>
        /// Creates database
        /// if Its created already it will use that instance
        /// </summary>
        /// <returns></returns>
        static async Task Init()
        {
            if(db != null) 
                return;

            db = new SQLiteAsyncConnection(DatabaseConstants.DatabasePath);
            await db.CreateTableAsync<Player>();
        }

        /// <summary>
        /// Adds player to the database
        /// </summary>
        /// <param name="playerName"></param>
        /// <param name="playerAlias"></param>
        /// <param name="playerTeam"></param>
        /// <returns>id</returns>
        public static async Task AddPlayerAsync(string playerName, string playerAlias, string playerTeam = null)
        {
            await Init();
            var player = new Player
            {
                Name = playerName, Alias = playerAlias, Team = playerTeam
            };
            await db.InsertAsync(player);
        }

Database is created in Init(), but halts on asynchronous db.CreateTableAsync<Player>() without throwing an exception.

View Model:

public partial class ManagePlayersPageViewModel : ObservableObject
    {
        /// <summary>
        /// List of players being displayed 
        /// </summary>
        [ObservableProperty] private ObservableCollection<Player> players;

        public ManagePlayersPageViewModel()
        {
            Players = PlayerService.GetAllPlayersAsync().Result.ToObservableCollection();
        }

I already cleaned and rebuild, updated dependencies and have raw.bundle.green.

0

1 Answer 1

2

Your code is "deadlocked". This Xamarin.Forms Q&A explains the concept. SQLite-NET-PCL Stuck on CreateTableAsync().

Bottom line: DO NOT use .Result with an async method. Especially in a constructor. Instead, get into an async context, by wrapping that code.

For Maui:

MainThread.BeginInvokeOnMainThread( async () =>
  {  // On MainThread.
    var players1 = await PlayerService.GetAllPlayersAsync();
    Players = players1.ToObservableCollection();
  });

OR, if GetAllPlayersAsync takes a long time, might be safer to call it from a background thread:

Task.Run( async () =>
  {  // On background thread.
    var players1 = await PlayerService.GetAllPlayersAsync();
    // Because Players affects UI, safest to get back on MainThread:
    MainThread.BeginInvokeOnMainThread( async () =>
      {  // On MainThread.
        Players = players1.ToObservableCollection();
      });
  });
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.