加载数据表速度慢时绑定到DataGridView.Datasource [英] Loading DataTable Slow When Bound to DataGridView.Datasource

查看:808
本文介绍了加载数据表速度慢时绑定到DataGridView.Datasource的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经找遍了,我不明白这一个。我的工作是拉,我需要在一个DataGridView中显示的行大量的一个WinForms UI。我已经阅读所有有关限制的行数和分页也绝对为我做这件事没有什么好办法。基本上我的工作扩展事件管理器为SQL Server 2008,我Codeplex上写的TargetDataViewer控制

I've searched all over and I can't figure this one out. I am working on a Winforms UI that is pulling large volumes of rows that I need to display in a DataGridView. I have already read all about limiting row counts and paging and there is absolutely no good way for me to do this. Basically I am working on the TargetDataViewer control of the Extended Events Manager for SQL Server 2008 that I wrote on Codeplex.

http://extendedeventmanager.codeplex.com/

我限制我能做什么基础上,具体的目标,以及它如何呈现的数据。我所试图做的是流已经从一个目标读入类似于如何探查器或SQL Server Management Studio中显示的数据,因为它。我重写了大量的代码流DataGridView的数据,并有一个BackgroundWorker获取数据并加工成一个DataTable。如果我没有设置DataGridView.DataSource =数据表,我可以加载300K +行数据到几分钟的数据表,它真的跑得快。当我的数据表的数据源添加慢几乎停止(而不是几分钟相同的300K行可以乘坐0.5小时)。

I am limited to what I can do based on the specific target and how it presents data. What I am trying to do is stream the data that has been read from a target into the DataGridView similar to how Profiler, or SQL Server Management Studio display data as it streams in. I rewrote a lot of code, and have a BackgroundWorker pulling data and processing it into a DataTable. If I don't set the DataGridView.DataSource = DataTable, I can load 300K+ rows of data into the DataTable in a few minutes, it really runs fast. As soon as I add the DataTable to the DataSource it slow to almost a halt (instead of a few minutes the same 300K rows can take a 1/2 hr).

我知道,这个问题是不是我处理的代码,它是专门针对被绑定到DataGridView.DataSource,我有时间代码来证明这一点。我无法弄清楚如何来解决这个问题。对于性能我可以晚将控件绑定到数据加载后的数据表,但是这是一个非常糟糕的用户体验。我看到很多人加载数据时,那么这可能只是一个限制我坚持抱怨DataGridView的性能影响?任何想法?

I know that the problem isn't my processing code, it is specific to being bound to the DataGridView.DataSource, and I have timing code to prove this. I can't figure out how to get around this. For Performance I can late bind the control to the DataTable after the data is loaded, but that is a really crappy user experience. I see lots of people complaining about the DataGridView performance impact when loading data so this may just be a limitation I am stuck with? Any ideas?

推荐答案

想想,当你填充会发生什么未绑定的数据表从一个的DataReader 一行:A 的DataRow 被创建,从填充 DataReader的,并添加到集合。然后,当你创建绑定, DataGridView的从表中提取数据,并建立屏幕上的视图。

Think about what happens when you populate an unbound DataTable with one row from a DataReader: A DataRow gets created, populated from the DataReader, and added to the Rows collection. Then, when you create the binding, the DataGridView pulls data from the table and builds the view on the screen.

数据表其绑定到 DataGridView的已启用,当你填充>会发生什么?事件处理一整得一塌糊涂。每次你改变一个绑定属性,属性更改事件被提出并绑定控件处理它。这不是发生30万次,这是发生30万次每个的。

What happens when you populate a DataTable whose binding to the DataGridView is enabled? A whole mess of event handling. Every time you change a bound property, the property-changed event gets raised and the bound control handles it. That's not happening 300,000 times, it's happening 300,000 times for each column.

如果您关闭这个功能,只是偶尔更新绑定控件?看看这个方法:

What if you turn this off, and only update the bound control occasionally? Look at this method:

private void PopulateDataTable()
{
    int rowCount = 10000;

    bindingSource1.RaiseListChangedEvents = false;
    for (int i = 0; i < rowCount; i++)
    {
        DataRow r = DT.NewRow();
        for (int j = 0; j < ColumnCount; j++)
        {
            r[j] = "Column" + (j + 1);
        }
        DT.Rows.Add(r);

        if (i % 500 == 0)
        {
            bindingSource1.RaiseListChangedEvents = true;
            bindingSource1.ResetBindings(false);
            Application.DoEvents();
            bindingSource1.RaiseListChangedEvents = false;
        }
    }
    bindingSource1.RaiseListChangedEvents = true
}

您必须调用ResetBindings强制绑定控件的更新。这需要时间,因为你不能围绕建设的DataGridViewRow 的对象,但取出事件的成本得到的是一个显著的改善。在我的机器,如果我填充有10列,10000行数据表,绑定到 DataGridView的,它需要2900毫秒。如果我离开数据绑定关闭的全部时间,它需要155毫秒。如果我重新绑定每500行,它需要840毫秒。

You have to call ResetBindings to force the update of the bound control. This takes time, because you can't get around the cost of building the DataGridViewRow objects, but taking out the events is a significant improvement. On my machine, if I populate a 10-column, 10000 row DataTable that's bound to a DataGridView, it takes 2900 milliseconds. If I leave data-binding turned off the entire time, it takes 155 milliseconds. If I reset the bindings every 500 rows, it takes 840 milliseconds.

当然,如果我被填充30万行的表,我也不会重置每500行绑定;我可能会在500行标志做一次,然后在操作完成之前将其关闭。但是,即使你做到这一点,你需要 Application.DoEvents 每隔一段时间打电话,从而使UI可以响应的事件。

Of course, if I were populating 300,000 row table, I wouldn't reset the bindings every 500 rows; I'd probably do it once at the 500-row mark and then turn it off until the operation completes. But even if you do this, you need to call Application.DoEvents every so often, so that the UI can respond to events.

修改

那有位 Application.DoEvents ;你并不需要做的,如果你在填充后台任务表​​。

Never mind that bit about Application.DoEvents; you don't need to do that if you're populating the table in a background task.

但是,你需要确保你重新设置绑定的在的BackgroundWorker ProgressChanged 事件处理程序,而不是在的DoWork 方法。而且你会体验到伤害的世界,如果你确实让用户的中绑定 DataGridView的当你填充它的数据修改的数据源在另一个线程。

But you do need to make sure that you're resetting the bindings in the BackgroundWorker's ProgressChanged event handler, and not in the DoWork method. And you're going to experience a world of hurt if you actually let the user edit data in the bound DataGridView while you're populating its data source on another thread.

这篇关于加载数据表速度慢时绑定到DataGridView.Datasource的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆