首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对DataGridView的非阻塞更新

对DataGridView的非阻塞更新
EN

Stack Overflow用户
提问于 2009-08-18 20:34:05
回答 3查看 4.1K关注 0票数 1

我知道如何使用委托来更新主控件线程上的控件,工作起来很棒。我这里的问题是,如果我向绑定的DataGridView添加一个大的DataSet (比如2000个项目),网格填充需要5-8秒,在这5-8秒期间,整个图形用户界面被锁定。如何更新DataGridView,使其不会锁定用户界面?

需要说明的是,问题不在于我对数据库执行的查询速度很慢,而是UI阻塞了,我已经有了DataSet object[],并将对象数组添加到DataGrid绑定到的BindingList<object>中,因此:

代码语言:javascript
运行
复制
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会导致问题。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-08-18 20:40:06

当GridView链接到DataSource时,您正在添加记录。这意味着它每次都会更新布局。

不如先填充DataSource,然后再设置DataSource属性如何?

代码语言:javascript
运行
复制
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循环可以转到另一个线程,但我认为您不需要这样做。

票数 1
EN

Stack Overflow用户

发布于 2009-08-18 20:58:27

就像尼克说的,BackgroundWorker可能是你最好的选择。

下面是一个非常简单的例子

代码语言:javascript
运行
复制
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();
    }
}
票数 3
EN

Stack Overflow用户

发布于 2009-08-18 20:39:42

研究如何使用BackgroundWorker.我自己对它们知之甚少,但在谷歌上搜索一下就会发现这是一个很好的可能性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1296340

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档