【百万级数据异步处理案例】 异步处理与界面交互 - 程序诗人 - 博客园

当我们读取一个大数据量的数据表的时候,如果采用直接读的方式,很容易造成界面成为“白板”的现象,这也是所谓的假死。这种方式并不是十分好,因为它不能让用户非常直观的看到界面(比如加入进度条显示进度),所以需要有一种手段来防止这种现象的发生。在.net中,要实现这种方式很容易,我们只要利用BeginInvoke开启异步操作即可。首先是开始前的准备工作,我们往Person表中插入一百万数据作为测试数据:

declare
@count int ,
@end int ;
begin
select @count = 1000000 ;
select @end = 0 ;
while @count > @end
insert into 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
{
public partial class MainFrm : Form
{
public MainFrm()
{
InitializeComponent();
}

private delegate DataTable GetDataFromDataBaseDelegate(); // 申明委托
private static string 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; // 返回填充好的数据集对象
}

// 回调函数,这里处理异步回调
private void 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);
// 反之直接绑定
}
}

private void BindListBox(DataTable dt)
{
this .lsbData.DataSource = dt;
}


private void MainFrm_Load( object sender, EventArgs e)
{

}

private void btnStart_Click( object sender, EventArgs e)
{
// 调用对象
GetDataFromDataBaseDelegate getData = new GetDataFromDataBaseDelegate(GetDataBaseLog);

// 开始进行异步调用
getData.BeginInvoke( new AsyncCallback(BindDataToListBoxCallBack), null );

// 这里可以干别的事情
tTick.Enabled = true ;
}

int iCount = 0 ;
// 这个测试异步处理的时候,做其他事情有没有影响的
private void tTick_Tick( object sender, EventArgs e)
{
++ iCount;
lblCount.Text
= iCount.ToString();
}
}
}

其实这里的执行流程就是:

首先,利用委托对象获取要执行的方法

然后,调用委托的BeginInvoke方法来开始异步执行。

 

京华志: 这样处理 可以很大程度的避免假死 非常不错的案例 值得大家学习

 

www.jinghuazhi.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值