.NET MAUI Sqlite数据库操作(二)异步初始化方法

一、异步初始化方法

private SQLiteAsyncConnection _database;public async Task Init()
{if (_database != null)return;var database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);await database.CreateTableAsync<TodoItem>();await database.CreateTableAsync<AnotherTableItem>();_database = database;
}

关键点
  1. 检查现有实例

    • 首先检查 _database 是否已被初始化。如果已经初始化,则直接返回,避免重复初始化。
  2. 创建并初始化数据库

    • 如果 _database 为空,则创建一个新的 SQLiteAsyncConnection 实例,并初始化所需的数据库表。
  3. 异步操作

    • 这是一个异步方法,使用 await 关键字来等待数据库表创建完成。
  4. 实例变量:

    • _database 是一个实例变量,存储数据库连接。
优缺点
  • 优点

    • 简单明了,直接在需要的地方调用 Init 方法即可。
    • 易于理解和实现。
  • 缺点

    • 在某些情况下,仍然有可能因为竞争条件而导致多次初始化(虽然通过检查 _database 可以减少这种情况,但并不能完全避免)。
    • 依赖于外部调用者必须记住在使用数据库之前调用 Init 方法。

 二、工厂方法模式

public class TodoItemDatabase
{private readonly SQLiteAsyncConnection _database;private TodoItemDatabase(SQLiteAsyncConnection database){_database = database;}public static async Task<TodoItemDatabase> CreateAsync(){var database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);var instance = new TodoItemDatabase(database);await instance.InitializeTables();return instance;}private async Task InitializeTables(){await _database.CreateTableAsync<TodoItem>();await _database.CreateTableAsync<AnotherTableItem>();}
}

关键点
  1. 私有构造函数

    • 构造函数被设为私有,确保只能通过 CreateAsync 方法来创建实例。
  2. 静态工厂方法

    • 使用一个静态异步方法 CreateAsync 来创建并初始化 TodoItemDatabase 实例。
    • CreateAsync 方法内部处理所有的初始化逻辑,并返回已初始化的实例。
  3. 实例化与初始化分离

    • 将实例化和初始化逻辑封装在一个静态方法中,确保创建的实例已经被正确初始化。
优缺点
  • 优点

    • 保证了实例在返回给调用者之前已经完全初始化,避免了未初始化或部分初始化的情况。
    • 更加面向对象,将创建逻辑封装在类内部,符合单一职责原则。
    • 易于测试,因为初始化逻辑是封装的,可以通过模拟 CreateAsync 方法来控制初始化过程。
  • 缺点

    • 相对来说实现稍微复杂一些。
    • 如果在应用程序生命周期中只需要一次初始化(例如单例模式),可能显得有些过度设计。

总结

  • 异步初始化方法:适合于简单且明确的初始化需求,如果能确保调用者始终在使用前调用 Init 方法,是一种较为直接的方式。
  • 工厂方法模式:适用于需要确保实例在任何时候都被正确初始化的场景,更加健壮和可扩展,特别是在复杂应用中,有利于维护和测试。

选择哪种方法取决于你具体的应用需求和复杂度。如果你的应用程序较为简单,异步初始化方法已经足够;如果你需要更高的鲁棒性和可维护性,工厂方法模式则是更好的选择。

三、双重检查锁定(Double-Checked Locking)

这种方法适用于多线程环境,确保资源只被初始化一次。

private static readonly object _lock = new object();
private SQLiteAsyncConnection _database;public async Task<SQLiteAsyncConnection> GetDatabaseAsync()
{if (_database == null){lock (_lock){if (_database == null){var database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);await database.CreateTableAsync<TodoItem>();await database.CreateTableAsync<AnotherTableItem>();_database = database;}}}return _database;
}

优缺点
  • 优点

    • 确保在多线程环境下资源只被初始化一次。
    • 性能较高,因为只在第一次初始化时加锁。
  • 缺点

    • 实现起来相对复杂一些。

四、懒加载(Lazy Initialization)

利用 Lazy<T> 类来实现异步懒加载。

private Lazy<Task<SQLiteAsyncConnection>> _databaseLazy = new Lazy<Task<SQLiteAsyncConnection>>(async () =>
{var database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);await database.CreateTableAsync<TodoItem>();await database.CreateTableAsync<AnotherTableItem>();return database;
});public Task<SQLiteAsyncConnection> GetDatabaseAsync()
{return _databaseLazy.Value;
}
优缺点
  • 优点

    • 简化了初始化逻辑。
    • 懒加载仅在首次访问时初始化。
  • 缺点

    • 异常处理较为复杂,需要特别注意捕获和处理异步初始化过程中的异常。

五、静态构造函数(Static Constructor)

 可以使用静态构造函数进行异步初始化(虽然静态构造函数本身不能是异步的,但可以在静态构造函数中启动异步初始化)。

private static SQLiteAsyncConnection _database;
private static Task _initializationTask;static MyClass()
{_initializationTask = InitializeDatabaseAsync();
}private static async Task InitializeDatabaseAsync()
{_database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);await _database.CreateTableAsync<TodoItem>();await _database.CreateTableAsync<AnotherTableItem>();
}public static async Task<SQLiteAsyncConnection> GetDatabaseAsync()
{await _initializationTask;return _database;
}
优缺点
  • 优点

    • 在类加载时就开始初始化,确保数据库连接在第一次使用时已经准备好。
  • 缺点

    • 如果初始化过程很长,可能会影响类的首次使用性能。

 六、线程安全的异步单例(Thread-Safe Async Singleton)

如果需要确保只有一个实例并且异步初始化,可以使用异步单例模式

private static readonly Lazy<Task<TodoItemDatabase>> _instance = new Lazy<Task<TodoItemDatabase>>(async () =>
{var database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);var instance = new TodoItemDatabase(database);await instance.InitializeTables();return instance;
});public static Task<TodoItemDatabase> Instance => _instance.Value;private async Task InitializeTables()
{await _database.CreateTableAsync<TodoItem>();await _database.CreateTableAsync<AnotherTableItem>();
}
优缺点
  • 优点

    • 确保全局只存在一个实例,并且该实例是异步初始化的。
  • 缺点

    • 实现起来稍微复杂,需要理解异步单例模式。

七、异步方法总结

每种方法都有其适用场景和优缺点。你可以根据以下因素选择合适的方法:

  • 简单性:如果你的应用程序较为简单,直接使用异步初始化方法或工厂方法模式即可。
  • 多线程环境:如果你的应用程序是多线程的,双重检查锁定或异步单例模式是更好的选择。
  • 延迟初始化:如果希望延迟到第一次使用时才初始化,可以考虑使用懒加载。

八、.NET MAUI Sqlite数据库操作(一)采用工厂模式补充完善

Constants.cs

using SQLite;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;namespace TodoSQLite
{public static class Constants{public const string DatabaseFilename = "TodoSQLite.db3"; // 数据库文件名public const SQLite.SQLiteOpenFlags Flags =// 以读写模式打开数据库。SQLite.SQLiteOpenFlags.ReadWrite |// 如果数据库文件不存在,则创建它。SQLite.SQLiteOpenFlags.Create |// 启用多线程数据库访问,以便多个线程可以共享数据库连接。SQLite.SQLiteOpenFlags.SharedCache;public static string DatabasePath => Path.Combine(FileSystem.AppDataDirectory, DatabaseFilename);}

 TodoItemDatabase.cs

public class TodoItemDatabase{private readonly SQLiteAsyncConnection _database;private TodoItemDatabase(SQLiteAsyncConnection database){_database = database;}public static async Task<TodoItemDatabase> CreateAsync(){var database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);var instance = new TodoItemDatabase(database);await instance.InitializeTables();return instance;}private async Task InitializeTables(){await _database.CreateTableAsync<TodoItem>();await _database.CreateTableAsync<AnotherTableItem>();}// 获取所有TodoItem项public Task<List<TodoItem>> GetItemsAsync(){return _database.Table<TodoItem>().ToListAsync();}// 获取未完成的TodoItem项public Task<List<TodoItem>> GetItemsNotDoneAsync(){return _database.Table<TodoItem>().Where(t => !t.Done).ToListAsync();}// 根据ID获取单个TodoItem项public Task<TodoItem> GetItemAsync(int id){return _database.Table<TodoItem>().Where(i => i.ID == id).FirstOrDefaultAsync();}// 保存或更新TodoItem项public Task<int> SaveItemAsync(TodoItem item){if (item.ID != 0){return _database.UpdateAsync(item);}else{return _database.InsertAsync(item);}}// 删除TodoItem项public Task<int> DeleteItemAsync(TodoItem item){return _database.DeleteAsync(item);}// 获取所有AnotherTableItem项public Task<List<AnotherTableItem>> GetAnotherTableItemsAsync(){return _database.Table<AnotherTableItem>().ToListAsync();}// 保存或更新AnotherTableItem项public Task<int> SaveAnotherTableItemAsync(AnotherTableItem item){if (item.ID != 0){return _database.UpdateAsync(item);}else{return _database.InsertAsync(item);}}// 删除AnotherTableItem项public Task<int> DeleteAnotherTableItemAsync(AnotherTableItem item){return _database.DeleteAsync(item);}}
}

完整思路都有了,仔细阅读,必能成功!

 关联阅读
​​​​​​​.NET MAUI Sqlite数据库操作(一)

.NET MAUI Sqlite数据库操作(二)异步初始化方法 ​​​​​​​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/349311.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

长亭培训加复习安全产品类别

下面这个很重要参加hw时要问你用的安全产品就有这个 检测类型产品 偏审计 安全防御类型 EDR类似于杀毒软件 安全评估 任何东西都要经过这个机械勘察才能上线 安全管理平台 比较杂 比较集成 审计 漏扫 评估 合在这一个平台 也有可能只是管理 主机理解为一个电脑 安了终端插件…

五、特征缩放和多项式回归

目录 一、为什么要使用特征缩放(Feature Scaling) 1.首先来看预测房价的例子 2.特征缩放前后效果对比 二、特征缩放方法 1.统一除以范围最大值 2.均值归一化(Mean Normalization) 3.Z-score标准化(Z-score Normalization) 4.一些可以接受/不接受的缩放范围 三、如何识别…

C# WPF入门学习主线篇(三十四)—— 图形和动画

C# WPF入门学习主线篇&#xff08;三十四&#xff09;—— 图形和动画 图形和动画是WPF的重要组成部分&#xff0c;能够大幅提升应用程序的用户体验。本篇博客将详细介绍WPF中图形和动画的使用方法&#xff0c;涵盖基本图形绘制、动画创建及多媒体的应用。通过本文&#xff0c;…

爆肝三天,制作属于自己的地图——DAY3(地图数据发布详细教程)

4&#xff0c;重建顶层。 倾斜摄影数据的组织方式&#xff0c;一个 Data 目录下的 Tile 可能会成千上万&#xff0c;如果不使用重建顶层&#xff0c;那么输出的3DTiles的包围盒会非常非常多&#xff0c;增加加载时长。重建顶层&#xff0c;程序会根据瓦片的空间结构关系采用八…

一文理清sshc包的使用场景和掌握两种连接方式及异常场景

一文理清sshc、ssh包的使用场景和两种连接方式 SSH协议SSH&#xff08;Secure Shell&#xff09;协议支持通过多种编程语言实现客户端和服务端的功能&#xff0c;包括Go、Python、Java、C#等。 GO语言 sshc包的使用建立连接1.DialWithKey2.DialWithPasswd 运行命令异常场景思维…

Git+Gitlab 远程库测试学习

Git远程仓库 1、Git远程仓库 何搭建Git远程仓库呢&#xff1f;我们可以借助互联网上提供的一些代码托管服务来实现 Gitee 码云是国内的一个代码托管平台&#xff0c;由于服务器在国内&#xff0c;所以相比于GitHub&#xff0c;码云速度会更快 码云 Gitee - 基于 Git 的代码托…

Mathtype插入word,以及mathtype在word上的卸载

1.Mathtype插入word 花了两个小时&#xff0c;最终得出的极品简单的安装方法&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; mathype下载地址&#xff1a;https://store.wiris.com/zh/products/mathtype/download/windows 下载完傻瓜式安装&#xff0c;不要…

集成学习模型对比优化—银行业务

1.Data Understanding 2.Data Exploration 3.Data Preparation 4.Training Models 5.Optimization Model 集成学习模型对比优化—银行业务 1.Data Understanding import pandas as pd from matplotlib import pyplot as plt import seaborn as sns df pd.read_csv(&quo…

如何通过 6 种方法从 iPhone 恢复已删除的文件

想知道如何从 iPhone 恢复已删除的文件吗&#xff1f;本文将指导您如何从 iPhone 恢复数据&#xff0c;无论您是否有 iTunes/iCloud 备份。 iPhone 上已删除的文件去哪儿了&#xff1f; 许多 iPhone 用户抱怨他们经常丢失 iPhone 上的一些重要文件。由于意外删除、iOS 更新失败…

安装golang

官网:All releases - The Go Programming Language (google.cn) 下载对应的版本安装即可

C++ 34 之 单例模式

#include <iostream> #include <string.h> using namespace std;class King{// 公共的函数&#xff0c;为了让外部可以获取唯一的实例 public:// getInstance 获取单例 约定俗成static King* getInstance(){return true_king;}private: // 私有化// 构造函数设置为…

2024 Idea最新激活码

idea的激活与安装 操作如下&#xff1a; ① 打开网站&#xff1a;https://web.52shizhan.cn 切换到&#xff1a;激活码&#xff0c;点击获取 ② 这个时候就跳转到现成账号页面&#xff0c;点击获取体验号&#xff0c;如图 ③ 来到了获取现成账号的页面了。输入你的邮箱账号即…

VRChat 2024年裁员原因与背景深度分析

VRChat&#xff0c;作为2022年元宇宙/VR社交领域的巨头&#xff0c;近期在2024年宣布裁员计划&#xff0c;其背后原因和背景值得业界尤其是仍在纯元宇宙虚拟空间创业的同仁们重点关注。 一、创始人决策失误 根据CEO的邮件披露&#xff0c;VRChat的创始人因缺乏经验和过度自信…

最新区块链论文速读--CCF A会议 ICSE 2024 共13篇 附pdf下载 (2/2)

Conference&#xff1a;International Conference on Software Engineering (ICSE) CCF level&#xff1a;CCF A Categories&#xff1a;Software Engineering/System Software/Programming Languages Year&#xff1a;2024 Num&#xff1a;13 第1~7篇区块链文章请点击此处…

大语言模型 (LLM) 红队测试:提前解决模型漏洞

大型语言模型 (LLM) 的兴起具有变革性&#xff0c;以其在自然语言处理和生成方面具有与人类相似的卓越能力&#xff0c;展现出巨大的潜力。然而&#xff0c;LLM 也被发现存在偏见、提供错误信息或幻觉、生成有害内容&#xff0c;甚至进行欺骗行为的情况。一些备受关注的事件包括…

什么充电宝牌子好用耐用?高评分绿联、西圣、罗马仕充电宝实测

在如今这个科技飞速发展的时代&#xff0c;充电宝已经成为我们日常生活中不可或缺的电子配件之一。当我们外出旅行、办公或者日常出行时&#xff0c;充电宝能够为我们的电子设备及时补充电量&#xff0c;让我们时刻保持在线。然而&#xff0c;面对市场上众多的充电宝品牌和型号…

小程序无法调用服务端问题排查

1、问题描述 突然有一天线上的小程序不能登录&#xff0c;经查小程序无法调用。经查无法小程序页面无法调用后台服务。 2、排查过程 由于无法登录小程序发布服务器&#xff0c;无法测试小程序前端服务器到服务端网络&#xff0c;并且小程序无法看到日志。所以就得从服务端和网…

idea有这个类却报红,无法用快捷键找到

idea有这个类却报红&#xff0c;无法用快捷键找到&#xff0c;但是项目启动却没有任何问题&#xff0c;严重影响到了开发效率&#xff0c;关idea 重新打开没有用。 找了一圈&#xff0c;办法如下&#xff1a; 1、点击左上角的 File—>Invalidate Caches/Restar 2、点击 In…

Vue CLI 4与项目构建实战指南

title: Vue CLI 4与项目构建实战指南 date: 2024/6/9 updated: 2024/6/9 excerpt: 这篇文章介绍了如何使用Vue CLI优化项目构建配置&#xff0c;提高开发效率&#xff0c;涉及配置管理、项目部署策略、插件系统定制以及Webpack和TypeScript的深度集成技巧。 categories: 前端…