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

.NET MAUI Android端SQLite初始化异常:主页无法加载

问题分析与解决方案

核心问题:构造函数同步阻塞异步方法引发死锁

你的WitbitsRepository构造函数中调用CreateTablesAsync().Wait(),这会在UI线程上触发死锁:

  • CreateTablesAsync()执行到await db.CreateTableAsync<Book>()时会释放当前UI线程
  • 但.Wait()强制同步等待,直接阻塞UI线程
  • 异步操作完成后需要回到UI线程继续执行,却发现线程已被阻塞,最终导致应用卡死,MainPage无法加载

修复步骤

1. 重构WitbitsRepository,规避构造函数阻塞

将数据库初始化逻辑移至异步方法,彻底放弃构造函数内的同步等待操作:

public class WitbitsRepository
{
    private SQLiteAsyncConnection db;

    // 私有构造函数,仅通过异步工厂方法创建实例
    private WitbitsRepository()
    {
        Debug.WriteLine("WitbitsRepository constructor called");
    }

    // 异步工厂方法,完成全量初始化
    public static async Task<WitbitsRepository> CreateAsync()
    {
        var repo = new WitbitsRepository();
        await repo.InitializeAsync();
        return repo;
    }

    private async Task InitializeAsync()
    {
        var databasePath = Path.Combine(FileSystem.AppDataDirectory, "Witbits.db");
        Debug.WriteLine("Database path: " + databasePath);

        if (!File.Exists(databasePath))
        {
            Debug.WriteLine("Database file not found at: " + databasePath);
            CopyDatabaseFromResource(databasePath);
        }
        else
        {
            Debug.WriteLine("Database file found at: " + databasePath);
        }

        db = new SQLiteAsyncConnection(databasePath);
        await CreateTablesAsync();
    }

    private async Task CreateTablesAsync()
    {
        await db.CreateTableAsync<Book>();
    }

    // 实现嵌入式资源复制逻辑
    private void CopyDatabaseFromResource(string targetPath)
    {
        // 注意替换为你的项目命名空间与资源路径
        using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("YourAppNamespace.Witbits.db");
        using var fileStream = new FileStream(targetPath, FileMode.Create);
        stream.CopyTo(fileStream);
    }
}

2. 修正App.xaml.cs的初始化逻辑

确保异步流程不阻塞,正确获取Repository实例:

public partial class App : Application
{
    public App()
    {
        InitializeComponent();
        _ = InitializeAppAsync(); // 用下划线避免异步警告,确保流程执行完成
    }

    private async Task InitializeAppAsync()
    {
        await InitializeDatabaseAsync();
        MainPage = new MainPage();
    }

    private async Task InitializeDatabaseAsync()
    {
        // 通过异步工厂方法创建Repository
        var repository = await WitbitsRepository.CreateAsync();
        // 若需全局复用,可将实例赋值给静态属性
        // App.GlobalRepository = repository;
    }

    // 可选:全局Repository实例
    // public static WitbitsRepository GlobalRepository { get; private set; }
}

3. 额外检查项

  • 确认嵌入式数据库文件的生成操作设置为「嵌入式资源」:在VS中选中Witbits.db,右键属性修改生成操作
  • 验证资源名称正确性:可通过Assembly.GetExecutingAssembly().GetManifestResourceNames()输出所有资源名称,匹配你的数据库资源路径
  • 确保Book类符合sqlite-net-pcl要求:需包含主键属性(用[PrimaryKey]标记)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 05:41:10