非阻塞的更新到一个DataGridView(Nonblocking update to a Data

2019-10-17 07:42发布

我知道如何使用委托给主控线程上更新的控制,就像一个魅力。 我在这里的问题是,如果我加入一个大的DataSet (比如2000项)到绑定DataGridView ,它需要5-8秒网格填充和5-8秒的整个GUI锁定期间。 我怎样才能更新DataGridView这样它不会锁定用户界面?

需要明确的是,该问题不是我正在做一个慢查询数据库和UI阻塞上,我已经有DataSet object[]和添加对象的阵列到BindingList<object>其中DataGrid必然如此:

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.DataSourceBindingList 。 这不会对我的工作,因为在我的列表中的对象不是静态的,它们分别上传数据异步的服务器,并将其复制到一个新BindingList会造成问题。

Answer 1:

您添加记录,而GridView控件被链接到的数据源。 这意味着它将每次更新的布局。

怎么样,你先填写您的数据源,然后才将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循环可以去到另一个线程,但我不认为你需要一个。



Answer 2:

就像尼克说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();
    }
}


Answer 3:

考虑使用一个BackgroundWorker。 我不知道太多关于他们自己,但在谷歌一点点搜索发现,作为一个很好的可能性。



文章来源: Nonblocking update to a DataGridView