我知道如何使用委托来更新主控件线程上的控件,工作起来很棒。我这里的问题是,如果我向绑定的DataGridView
添加一个大的DataSet
(比如2000个项目),网格填充需要5-8秒,在这5-8秒期间,整个图形用户界面被锁定。如何更新DataGridView
,使其不会锁定用户界面?
需要说明的是,问题不在于我对数据库执行的查询速度很慢,而是UI阻塞了,我已经有了DataSet object[]
,并将对象数组添加到DataGrid
绑定到的BindingList<object>
中,因此:
BindingList<object> dataProvider = new BindingList<object>();
DataGridView gridView = new DataGridView();
gridView.DataSource = dataProvider;
// ...stuff happens...
object[] source = dataSet; //of 2000 items
foreach (object item in source) { //this foreach blocks
dataProvider.Add(item);
}
我尝试了各种方法(我知道不会起作用,但我想我会明白的),比如创建一个执行dataProvider.Add()
的委托,但这并不重要,因为它仍然必须在控制线程上发生。
有几个很好的建议是围绕着首先构建BindingList
,然后设置gridView.DataSource
。虽然这是有效的(它会立即更新网格),但我看到的添加更多数据的唯一方法是创建另一个新的BindingList
,执行一个gridView.DataSource.copyTo()
(以获取现有数据),并在其上添加新数据,然后将gridView.DataSource
设置为新的BindingList
。这对我不起作用,因为我的列表中的对象不是静态的,它们都异步地将数据上传到服务器,并且将它们复制到新的BindingList
会导致问题。
发布于 2009-08-18 20:40:06
当GridView链接到DataSource时,您正在添加记录。这意味着它每次都会更新布局。
不如先填充DataSource,然后再设置DataSource属性如何?
gridView.DataSource = null;
...stuff happens...
object[] source = dataSet; //of 2000 items
foreach (object item in source) { //this foreach blocks
dataProvider.Add(item);
}
gridView.DataSource = dataProvider;
foreach循环可以转到另一个线程,但我认为您不需要这样做。
发布于 2009-08-18 20:58:27
就像尼克说的,BackgroundWorker
可能是你最好的选择。
下面是一个非常简单的例子
public partial class Form1 : Form
{
BackgroundWorker b = new BackgroundWorker();
public Form1()
{
InitializeComponent();
b.RunWorkerCompleted += new RunWorkerCompletedEventHandler(b_RunWorkerCompleted);
b.DoWork += new DoWorkEventHandler(b_DoWork);
}
void b_DoWork(object sender, DoWorkEventArgs e)
{
// build dataset here and assigning it to results
e.Result = dataset;
}
void b_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// assign the dataset you built in DoWork in the gridview and update it
dataGridView1.DataSource = e.Result;
dataGridView1.Update();
}
private void button1_Click(object sender, EventArgs e)
{
b.RunWorkerAsync();
}
}
发布于 2009-08-18 20:39:42
研究如何使用BackgroundWorker.我自己对它们知之甚少,但在谷歌上搜索一下就会发现这是一个很好的可能性。
https://stackoverflow.com/questions/1296340
复制相似问题