在.NET架构的Winform项目中引入“异步编程”思想和技术
- 一、异步编程引入
- (1)异步编程引入背景
- (2)异步编程程序控制流图
- (3)异步编程前置知识:
- 二、异步编程demo
- 步骤1:
- 步骤2:
- 步骤3:
- 效果:
一、异步编程引入
(1)异步编程引入背景
在当今的软件开发领域,提升用户体验是至关重要的。通过采用异步编程,我们能够在不阻塞UI线程的同时,有效地处理I/O密集型任务或在后台线程中执行CPU密集型任务。这种方法不仅提高了程序的效率,还符合人体工程学原则,使得用户界面更加友好。
(2)异步编程程序控制流图
(3)异步编程前置知识:
进程:CPU(处理机)分配资源的最小单位
线程:CPU处理任务的最小单位
进程与线程的关系:
进程同步:多个进程上处理机运行具有顺序关系,前一个执行了后一个才能执行
进程互斥:某些资源同一时间只允许一个进程使用
I/O密集型任务:如打印机打印、网络I/O、磁盘I/O,任务的瓶颈是I/O系统的速度
CPU密集型任务:如复杂的数学计算、加密算法,任务的瓶颈是CPU的计算能力
C#中异步编程的三个主要对象:
- async:用于声明当前函数是一个异步函数
- await:用于标记异步函数的暂停点,只能在async声明的函数中使用
- Task或Task<>:一个异步操作的类,用于执行异步操作
二、异步编程demo
目标框架:.NET Framework 4.7.2
针对的功能:磁盘I/O和网络I/O
步骤1:
将事件中的所有操作封装到一个异步函数中,这里以按钮的点击事件为例
原来的代码:
private void button1_Click(object sender, EventArgs e)
{
//点击事件的代码逻辑
}
封装后的代码:
private void button1_Click(object sender, EventArgs e)
{
// 封装为函数,异步执行登录验证
await LoginAsync();
// 控制权交还给UI线程,此处可添加登录成功后的后续操操作
}
private async Task LoginAsync()
{
//点击事件的代码逻辑
}
这里还演示了异步函数的调用,使用await关键字进行异步函数的异步调用,调用异步函数后,程序的控制权立即返回调用线程(UI线程),因此UI不会卡顿。
步骤2:
通过关键字async将控件 的事件声明为异步事件
原来的代码
private void button1_Click(object sender, EventArgs e)
{
}
修改后的代码
private async void button1_Click(object sender, EventArgs e)
{
}
步骤3:
在封装的函数中调用服务的异步方法,这里以数据库服务为例,调用MySql.Data.MySqlClient中的异步数据库操作函数OpenAsync
、ExecuteReaderAsync
和ReadAsync
。
原来的代码:
con.Open();
MySqlDataReader reader = cmd.ExecuteReader();
// 检查是否有查询结果
if (reader.Read())
修改后的代码:
await con.OpenAsync();
var reader = await cmd.ExecuteReaderAsync())
if (await reader.ReadAsync())
效果:
目前我的数据库连接字符串是一个错误的字符串,如果不引入异步编程,在登录时,程序从请求数据库连接,到数据库返回数据库连接的状态(成功/失败)这段时间内,UI是冻结的,不允许任何其他操作,也不允许移动窗体。但是在引入上述异步编程技术之后,UI不会冻结,用户体验感上升。