当我们读取一个大数据量的数据表的时候,如果采用直接读的方式,很容易造成界面成为“白板”的现象,这也是所谓的假死。这种方式并不是十分好,因为它不能让用户非常直观的看到界面(比如加入进度条显示进度),所以需要有一种手段来防止这种现象的发生。在.net中,要实现这种方式很容易,我们只要利用BeginInvoke开启异步操作即可。首先是开始前的准备工作,我们往Person表中插入一百万数据作为测试数据:
declare
@countint,
@endint;
begin
select@count=1000000;
select@end=0;
while@count>@end
insertinto Person(PER_FIRST_NAME,PER_Last_NAME,PER_BIRTH_DATE,PER_WEIGHT_KG,PER_HEIGHT_M)
values('11111','2222222',GETDATE(),34,45)
set@count=@count-1
end
然后就是全部的操作代码,我坐上了详细的注释:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
using System.Runtime.Remoting.Messaging;
namespace ReadBigDataFromOracle
{
publicpartialclass MainFrm : Form
{
public MainFrm()
{
InitializeComponent();
}
privatedelegate DataTable GetDataFromDataBaseDelegate(); //申明委托
privatestaticstring connStr ="server=.;uid=sa;pwd=251147;database=iBatisDemo;";
//从数据库提取大数据量的数据,这里是造成界面假死的原因
private DataTable GetDataBaseLog()
{
string sql ="select * from Person";
DataTable dt =new DataTable();
using (SqlConnection conn =new SqlConnection(connStr))
{
conn.Open();
SqlCommand cmd =new SqlCommand(sql, conn);
SqlDataAdapter sda =new SqlDataAdapter(cmd);
sda.Fill(dt);
}
return dt; //返回填充好的数据集对象
}
//回调函数,这里处理异步回调
privatevoid BindDataToListBoxCallBack(IAsyncResult iar)
{
AsyncResult result = (AsyncResult)iar;
GetDataFromDataBaseDelegate getDataDelegate = (GetDataFromDataBaseDelegate)result.AsyncDelegate; //得到委托对象
DataTable dt = getDataDelegate.EndInvoke(iar); //得到异步处理的结果
if (this.lsbData.InvokeRequired) //如果出现线程和界面交互
{
this.Invoke(new MethodInvoker(delegate()
{
BindListBox(dt); //绑定数据到ListBox
}
));
}
else
{
BindListBox(dt); //反之直接绑定
}
}
privatevoid BindListBox(DataTable dt)
{
this.lsbData.DataSource = dt;
}
privatevoid MainFrm_Load(object sender, EventArgs e)
{
}
privatevoid btnStart_Click(object sender, EventArgs e)
{
//调用对象
GetDataFromDataBaseDelegate getData =new GetDataFromDataBaseDelegate(GetDataBaseLog);
//开始进行异步调用
getData.BeginInvoke(new AsyncCallback(BindDataToListBoxCallBack), null);
//这里可以干别的事情
tTick.Enabled =true;
}
int iCount =0;
//这个测试异步处理的时候,做其他事情有没有影响的
privatevoid tTick_Tick(object sender, EventArgs e)
{
++iCount;
lblCount.Text = iCount.ToString();
}
}
}
其实这里的执行流程就是:
首先,利用委托对象获取要执行的方法
然后,调用委托的BeginInvoke方法来开始异步执行。
分类:
.NET 异步委托
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2010-09-13 C#如何实现从内存中加载程序集
2010-09-13 JQuery最佳实践:JQuery自定义事件的应用
2010-09-13 ASP.NET中大结果集的分页