You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQLite异步创建Player表无异常停滞问题求助

问题根源与解决方案

核心问题:同步阻塞异步方法导致死锁

你的代码停滞无异常的直接原因是ViewModel构造函数中使用.Result同步阻塞异步方法,造成了上下文死锁:

  • await关键字默认会捕获当前UI线程上下文,异步操作完成后需要回到该上下文继续执行
  • 但.Result会阻塞UI线程等待异步方法完成,导致db.CreateTableAsync<Player>()执行到await后无法回到UI线程,最终卡死

修复步骤

1. 重构ViewModel,移除同步阻塞调用

不要在构造函数中同步调用异步方法,改用异步初始化模式:

public partial class ManagePlayersPageViewModel : ObservableObject
{
    [ObservableProperty] private ObservableCollection<Player> players;

    // 异步初始化方法,替代构造函数中的同步调用
    public async Task InitializeAsync()
    {
        var playerList = await PlayerService.GetAllPlayersAsync();
        Players = playerList.ToObservableCollection();
    }
}

2. 在页面生命周期中触发异步初始化

在对应页面的代码文件(如ManagePlayersPage.xaml.cs)中,通过页面生命周期方法调用初始化:

protected override async void OnAppearing()
{
    base.OnAppearing();
    if (BindingContext is ManagePlayersPageViewModel vm)
    {
        await vm.InitializeAsync();
    }
}

3. 确保PlayerService的异步方法实现正确

补充/检查GetAllPlayersAsync方法的实现,确保它正确调用Init:

public static class PlayerService
{ 
    private static SQLiteAsyncConnection db;

    static async Task Init()
    {
        if(db != null) 
            return;

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

    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);
    }

    // 补充GetAllPlayersAsync方法
    public static async Task<List<Player>> GetAllPlayersAsync()
    {
        await Init();
        return await db.Table<Player>().ToListAsync();
    }
}

4. 验证Player实体类的SQLite属性

确保实体类正确标记了SQLite所需的属性(比如主键):

public class Player
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    public string Name { get; set; }
    public string Alias { get; set; }
    public string Team { get; set; }
}

5. 确认数据库路径配置正确

检查DatabaseConstants的路径是否适配平台(如MAUI/Xamarin):

public static class DatabaseConstants
{
    public const string DatabaseFileName = "Player.db3";
    public static string DatabasePath => Path.Combine(FileSystem.AppDataDirectory, DatabaseFileName);
}

内容的提问来源于stack exchange,提问作者Jean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 22:16:30