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

.NET 8 MAUI Android应用中ToListAsync()是否可用?如何异步查询数据?

问题解决:.NET 8 MAUI Android中SQLite异步查询与空异常修复

核心问题分析

你遇到的空异常和ToListAsync()不可用的问题,根源在于两个关键点:

  1. 异步初始化方法未正确等待,导致数据库连接未完成初始化就被访问,触发空引用异常;
  2. 使用了同步的SQLiteConnection,该类不提供异步查询方法,自然无法使用ToListAsync()。

.NET 8 MAUI Android完全支持ToListAsync(),但需要配合异步版本的SQLite连接类使用。以下是具体修复方案:


第一步:切换到SQLiteAsyncConnection

将同步的SQLiteConnection替换为SQLiteAsyncConnection,这是SQLite-net库提供的异步连接实现,支持所有异步操作API。

第二步:修复数据库初始化逻辑

确保初始化方法被正确等待,并且只执行一次,避免重复创建数据库连接和表。

第三步:替换所有同步操作为异步方法

将CreateTable、Insert、ToList等同步方法,替换为对应的异步版本CreateTableAsync、InsertAllAsync(批量插入更高效)、ToListAsync。

修改后的DataContext代码

public class DataContext
{
    private const string DbName = "IdealDiagnosisDb3";
    public static string DbPath = Path.Combine(FileSystem.Current.AppDataDirectory, DbName);
    private SQLiteAsyncConnection _database;
    private bool _isInitialized = false; // 标记初始化状态,避免重复执行

    private async Task Init()
    {
        if (_isInitialized) return;
        
        _database = new SQLiteAsyncConnection(DbPath, SQLiteOpenFlags.Create | SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.SharedCache);

        if (File.Exists(DbPath))
        {
            _isInitialized = true;
            return;
        }

        // 异步创建表
        await _database.CreateTableAsync<Drug>();
        List<Drug> drugs = new List<Drug>(){ /* 你的大数据集合 */ };
        // 批量插入,比循环单条插入性能提升数倍
        await _database.InsertAllAsync(drugs);

        await _database.CreateTableAsync<TradeDrug>();
        List<TradeDrug> tradeDrugs = new List<TradeDrug>(){ /* 你的大数据集合 */ };
        await _database.InsertAllAsync(tradeDrugs);

        _isInitialized = true;
    }
    
    public async Task<List<Drug>> LoadAllDrugsAsync()
    {
        await Init();
        return await _database.Table<Drug>().ToListAsync();
    }

    public async Task<List<TradeDrug>> LoadAllTradeDrugsAsync()
    {
        await Init();
        return await _database.Table<TradeDrug>().ToListAsync();
    }
}

第四步:修复ViewModel中的异步调用问题

你的OnIsTradeRadioButtonCheckedChanged方法调用异步的Search()但未等待,可能导致UI更新异常,需要调整:

partial async void OnIsTradeRadioButtonCheckedChanged(bool value)
{
    await Search();
}

另外,针对8000条数据的过滤操作,建议放到后台线程执行,避免UI卡顿:

if (!string.IsNullOrEmpty(SearchName))
{
    IsBusy = true;
    // 后台线程执行过滤逻辑
    Drugs = await Task.Run(() => 
        DrugsWithoutFilter.Where(x => x.DrugName.ToLower().Contains(SearchName.ToLower())).ToList()
    );
    CountDrugs = Drugs.Count();
    IsBusy = false;
}

关键说明

  1. 空异常修复:原代码中init()是异步方法,但调用时未加await,导致Database还未赋值就被访问,触发空引用异常。修改后通过await Init()确保数据库连接初始化完成后再执行查询。
  2. ToListAsync()支持:只有SQLiteAsyncConnection才提供ToListAsync()等异步扩展方法,同步连接无此能力。
  3. 性能优化:批量插入InsertAllAsync相比循环单条插入,能大幅提升8000条数据的初始化速度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 11:50:14