C# 使用 APM 模式实现异步数据绑定 DataGridView
在 Windows 窗体应用开发中,直接同步执行数据库查询会导致 UI 线程阻塞,程序界面无响应。利用 .NET 的异步编程模型(APM),即 BeginExecuteReader 和 EndExecuteReader 方法,可以在后台线程获取数据,并通过跨线程调用(Invoke)将结果安全地展示在 DataGridView 上。
为什么需要异步绑定数据?
默认情况下,SQL 命令的执行是同步的。如果查询耗时较长,主线程会被挂起,导致整个窗口“假死”。采用异步方式可以让请求在后台运行,保持界面的交互性。
核心实现逻辑
该方案主要包含以下几个关键步骤:
- 连接配置:在连接字符串中添加
Asynchronous Processing=true,以启用 SQL Client 的异步支持。 - 启动异步读取:使用
SqlCommand对象的BeginExecuteReader方法发起请求,并传入回调函数。 - 处理回调:在异步完成后的回调方法
AsyncCallBack中,调用EndExecuteReader获取数据流,并将其加载到DataTable中。 - 跨线程更新:由于 UI 控件只能由创建它的线程访问,因此必须检查
InvokeRequired。如果为真,则使用Invoke方法将数据设置任务封送回 UI 线程执行。
完整代码示例
以下类封装了异步回调操作,可直接集成到你的项目中。注意修改命名空间和引用。
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Windows.Forms;
namespace WindowsApplication2
{
public class AsyncCallBackOperation
{
// 静态引用用于在回调中访问控件,实际项目中建议传递实例或使用更健壮的数据结构
private static DataGridView dataGridView;
///
/// 发起异步数据库查询
///
/// 数据库连接字符串
/// SQL 查询语句
/// 目标 DataGridView 控件
public static void AsyncCallBack(string connectionString, string sql, DataGridView dgv)
{
dataGridView = dgv;
// 关键:启用异步处理
connectionString += ";Asynchronous Processing=true";
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand(sql, conn);
conn.Open();
// 开始异步读取,注册回调方法
command.BeginExecuteReader(new AsyncCallback(AsyncCallBack), command);
}
///
/// 异步回调方法
///
/// 异步状态
static void AsyncCallBack(IAsyncResult ar)
{
if (ar.IsCompleted)
{
// 从 AsyncState 获取原始命令对象
SqlCommand com = (SqlCommand)ar.AsyncState;
SqlDataReader dr = null;
try
{
dr = com.EndExecuteReader(ar);
DataTable dt = new DataTable();
dt.Load(dr);
// 关闭读取器
dr.Close();
}
catch (Exception ex)
{
// 建议在实际应用中添加日志记录或错误提示
return;
}
// 检查是否需要跨线程调用
if (dataGridView.InvokeRequired)
{
updateDG ur = new updateDG(dataBin);
// 将更新 UI 的操作封送回 UI 线程
dataGridView.Invoke(ur, dt);
}
}
}
delegate void updateDG(DataTable dt);
///
/// 实际的数据绑定方法
///
/// 数据表
public static void dataBin(DataTable dt)
{
if (dt.Rows.Count > 0)
{
dataGridView.DataSource = dt;
}
else
{
dataGridView.DataSource = null;
}
}
}
}
使用注意事项
资源释放: 上述代码中 SqlConnection 在 Open 后并未显式关闭。在更严谨的生产环境中,建议在 try...finally 块中确保连接被正确处置,或者使用 using 语句包裹 SqlConnection 和 SqlCommand 的生命周期管理,尽管在异步场景下这需要更细致的状态追踪。
现代替代方案: 如果你使用的是较新版本的 .NET (4.5+),推荐直接使用基于 Task 的异步 API(如 ExecuteReaderAsync)配合 async/await 关键字,这比传统的 APM 模式更具可读性和维护性。但在遗留系统中,上述 APM 方案依然有效。
以上就是 C# 异步绑定数据实现方法的详细内容,更多关于 C# 多线程与数据库交互的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









