.NET 8 MAUI Android应用中ToListAsync()是否可用?如何异步查询数据?
问题解决:.NET 8 MAUI Android中SQLite异步查询与空异常修复
核心问题分析
你遇到的空异常和ToListAsync()不可用的问题,根源在于两个关键点:
- 异步初始化方法未正确等待,导致数据库连接未完成初始化就被访问,触发空引用异常;
- 使用了同步的
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; }
关键说明
- 空异常修复:原代码中
init()是异步方法,但调用时未加await,导致Database还未赋值就被访问,触发空引用异常。修改后通过await Init()确保数据库连接初始化完成后再执行查询。 - ToListAsync()支持:只有
SQLiteAsyncConnection才提供ToListAsync()等异步扩展方法,同步连接无此能力。 - 性能优化:批量插入
InsertAllAsync相比循环单条插入,能大幅提升8000条数据的初始化速度。
内容的提问来源于stack exchange,提问作者amr yakout
相关产品推荐
相关产品推荐

