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
.
CodePudding user response:
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();
});
});