【百萬級數據異步處理案例】 異步處理與界面交互 - 程序詩人 - 博客園

當我們讀取一個大數據量的數據表的時候,如果採用直接讀的方式,很容易造成界面成爲“白板”的現象,這也是所謂的假死。這種方式並不是十分好,因爲它不能讓用戶非常直觀的看到界面(比如加入進度條顯示進度),所以需要有一種手段來防止這種現象的發生。在.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方法來開始異步執行。

 

京華志: 這樣處理 可以很大程度的避免假死 非常不錯的案例 值得大家學習

 

www.jinghuazhi.com

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章