使用Backgroundworker将大量数据加载到ListViewItem
本文关键字:加载 ListViewItem 数据 Backgroundworker 使用 | 更新日期: 2023-09-27 18:27:12
使用Backgroundworker 将大量数据加载到ListViewItem
当我准备打开一个表单时,我在加载大量数据时遇到了问题。所以我在表单中实现了一个BackgroundWorker组件,这就是我的代码的样子。
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int x = 1; x <= 100; x++)
{
loadDataByAll(); //Loads All Data to ListView
backgroundWorker1.RunWorkerAsync();
backgroundWorker1.ReportProgress(x);
}
}
对于过程更改事件代码
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
对于loadDataByAll()函数
private void loadDataByAll()
{
try
{
lviewGuard.Items.Clear();
con.ConnectionString = dbcon.getConnectionString();
con.Open();
String query = "SELECT guardid AS a, g_firstname AS b, g_midname AS c, g_lastname AS d, g_age AS e, g_gender AS f, g_address AS g, g_contactno AS h, g_licno AS i, g_lic_until AS j, g_assigned_client AS k, g_schedule_from AS l, g_schedule_to AS m, app_no AS n";
query += " FROM guards";
query += " WHERE resigned = '0' ORDER BY app_no DESC";
OleDbCommand cmd = new OleDbCommand(query, con);
cmd.ExecuteScalar();
OleDbDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
lviewGuard.BeginUpdate();
ListViewItem lv = new ListViewItem(rdr["a"].ToString());
lv.SubItems.Add(rdr["b"].ToString());
lv.SubItems.Add(rdr["c"].ToString());
lv.SubItems.Add(rdr["d"].ToString());
lv.SubItems.Add(rdr["e"].ToString());
lv.SubItems.Add(rdr["f"].ToString());
lv.SubItems.Add(rdr["g"].ToString());
lv.SubItems.Add(rdr["h"].ToString());
lv.SubItems.Add(rdr["i"].ToString());
lv.SubItems.Add(rdr["j"].ToString());
lv.SubItems.Add(rdr["k"].ToString());
lv.SubItems.Add(rdr["l"].ToString());
lv.SubItems.Add(rdr["m"].ToString());
lv.SubItems.Add(rdr["n"].ToString());
lviewGuard.Items.Add(lv);
lviewGuard.EndUpdate();
}
con.Close();
}
catch (Exception)
{
MessageBox.Show("MDB Database is not Present", "Microsoft Access Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.ExitThread();
}
}
最后我的按钮实现
private void btnGo7_Click(object sender, EventArgs e)
{
for (int x = 1; x <= 100; x++)
{
btnGo7.Text = "Running";
btnGo7.Enabled = false;
}
btnGo7.Text = "Go";
btnGo7.Enabled = true;
progressBar1.Value = 0;
tabControl1.Visible = false;
}
很抱歉在阅读此代码时浪费了您的时间。我真的对这个多线程和后台工作一无所知。
I建议将数据加载到列表中,并将listview置于虚拟模式。
http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.virtualmode.aspx
为每一行创建一个listviewitem是没有用的。尝试
减少所选的行。(没有人在阅读100万个listviewitems)。在虚拟模式下设置列表视图。。
如果你想坚持你的版本:
如果loadDataByAll()正在线程上运行,请不要触摸listview控件!
我会这样做:(不要把我钉在打字错误上,不要测试)
private void loadDataByAll()
{
try
{
// lviewGuard.Items.Clear();
con.ConnectionString = dbcon.getConnectionString();
con.Open();
String query = "SELECT guardid AS a, g_firstname AS b, g_midname AS c, g_lastname AS d, g_age AS e, g_gender AS f, g_address AS g, g_contactno AS h, g_licno AS i, g_lic_until AS j, g_assigned_client AS k, g_schedule_from AS l, g_schedule_to AS m, app_no AS n";
query += " FROM guards";
query += " WHERE resigned = '0' ORDER BY app_no DESC";
OleDbCommand cmd = new OleDbCommand(query, con);
cmd.ExecuteScalar();
OleDbDataReader rdr = cmd.ExecuteReader();
List<obj> data = new List<obj>();
while (rdr.Read())
{
data.Add( new obj
{
a = rdr["a"],
b = rdr["b"]
});
}
con.Close();
this.Invoke(new Action(delegate { UpdateListview(data); }));
}
catch (Exception)
{
MessageBox.Show("MDB Database is not Present", "Microsoft Access Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.ExitThread();
}
}
public void UpdateListview(List<obj> data)
{
lviewGuard.BeginUpdate();
lviewGuard.Items.Clear();
foreach(obj o in data)
{
ListViewItem lv = new ListViewItem(rdr["a"].ToString());
lv.SubItems.Add(o.b.ToString());
lv.SubItems.Add(o.c.ToString());
lviewGuard.Items.Add(lv);
}
lviewGuard.EndUpdate();
}